문제 분석
- 세 개의 장대가 있다
- 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다.
- 각 원판은 반경이 큰 순서대로 쌓여있다.
- 제약 조건에 따라 원판을 첫 번째 장대에서 세 번째 장대로 옮긴다.
제약 조건
- 한 번에 한개의 원판만을 다른 탑으로 옮길 수 있다.
- 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
- 이동 횟수는 최소가 되어야 한다.
출력 양식
- 첫째 줄에 옮긴 횟수 K를 출력한다.
- 두 번째 줄부터 수행 과정을 출력한다.
- K개의 줄에 걸쳐 두 정수 A B를 빈칸을 두고 출력한다.
- A번째 탑의 가장 위에 있는 원판을 B번째 탑의 가장 위로 옮긴다는 뜻.
발상
-
가장 밑에 원판이 목적지에 가려면 그 원판을 제외한 나머지 원판들은 순서대로 목적지가 아닌 다른 곳에 쌓여 있어야 한다
-
재귀는 두가지로 분기 된다.
- 가장 밑 (N번째) 원판이 목적지로 가는 재귀
- 그 다음번째 원판들( 1~(N-1) )이 목적지로 가는 재귀
-
가장 큰 원판이 움직일 수 있도록 나머지 원판들이 경유지로 비켜주고 가장 큰 원판이 움직인다.
-
포인트는 각 재귀의 깊이 마다 목적지와 경유지가 바뀐다는 사실을 인지하는 것이다.
-
원판의 개수가 짝수인지 홀수인지에 따라서도 처음 움직이는 원판의 위치도 달라진다.
구현
import java.util.Scanner;
public class Num11729 {
//하노이 타워
static int cnt = 0;
public static void rec(int num, int from, int by, int to, StringBuilder sb){
if (num == 0) return;
rec(num-1, from, to, by, sb); //n-1개의 원판을 가운데로 옮겨 주고
cnt++;
sb.append(from)
.append(" ")
.append(to)
.append("\n");
rec(num-1, by, from, to, sb);//남은 n-1개의 원판을 목적지로 옮겨 준다.
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
StringBuilder sb = new StringBuilder();
rec(n, 1,2,3, sb);
System.out.println(cnt);
System.out.println(sb.toString());
}
}
결과
'Algorithm' 카테고리의 다른 글
A. 탐욕법 (Greedy) (0) | 2021.05.26 |
---|---|
[백준/BOJ 1074] Z (Java) (0) | 2021.05.10 |
[백준/BOJ 1662] 압축 (Java) (0) | 2021.05.05 |