https://www.acmicpc.net/problem/11729
11729번: 하노이 탑 이동 순서
세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로
www.acmicpc.net
문제
문제 풀이
- 전형적인 재귀함수 문제다.
- 왜 재귀인가?
1) N개의 원판이 있을 때, 크기가 N인 마지막 원판을 1 ➡ 3으로 옮겨야한다.
2) N - 1 개의 원판들이 모두 1 ➡ 2로 옮겨져야한다.
3) 크기가 N - 1인 마지막 원판을 1 ➡ 2로 옮겨야한다.
4) N - 2 개의 원판들이 모두 1 ➡ 3으로 옮겨야한다.
... ...
1) ~ 4)와 같은 순서로 계속 반복될 것이다. - Hanoi(N)은 Hanoi(N-1) + N(1 ➡ 3)이다.
- 재귀 함수 구현시 어려웠던 점
여기까지 알아내놓고, 구현을 못하고 있었다. 원판을 어떻게 표현해야되지?
단순하게 1, 2, 3 을 매개 변수 start, mid, dest 로 넣으면 쉬운 거였다. - 푼 방법
1. N - 1 개의 원판을 start ➡ mid 로 옮긴다 ( Hanoi(start , mid) )
2. N을 start ➡ dest 으로 옮긴다.
3. N - 1 개의 원판을 다시 mid ➡ dest 로 옮긴다 ( Hanoi(mid, dest) )
-이 과정에서 다시 재귀가 들어갈 것이다.
*이걸 못해서 한참 고민했다...
4. base case는 무엇일까? N 이 1 일 때, 그니까 마지막 원판이 남았을 때, 그걸 destination까지 옮기면 된다.
JAVA code
import java.io.*;
public class baekjoon11729 {
public static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
sb.append((int) Math.pow(2, N) - 1).append('\n');
Hanoi(N, 1, 2, 3);
System.out.println(sb);
}
static void Hanoi(int N, int start, int mid, int dest) {
// 원판이 하나일때
if (N == 1) {
sb.append(start + " " + dest + "\n");
return;
}
// A에서 C로 옮긴다고 가정할 때,
// Step 1 : N - 1 개를 A에서 B로 이동
Hanoi(N - 1, start, dest, mid);
// Step 2 : 1개를 A에서 C로 이동
sb.append(start + " " + dest + "\n");
// Step 3 : B로 이동된 N - 1 개를 B에서 C로 이동
Hanoi(N - 1, mid, start, dest);
}
}
'백준 문제풀이' 카테고리의 다른 글
[백준] 7568번 덩치 - 브루트 포스(1) [JAVA] (2) | 2022.10.04 |
---|---|
[백준] 17478번 재귀함수가 뭔가요? - 재귀(5) [JAVA] (0) | 2022.09.29 |
[백준] 2447번 별 찍기 10 - 재귀(3), 분할정복(1) [JAVA] (0) | 2022.09.28 |
[백준] 피보나치 수 5 - 재귀(2) [JAVA] (0) | 2022.09.27 |
[백준] 10872번 팩토리얼 - 재귀(1) [JAVA] (0) | 2022.09.27 |