BOJ 11729

2020-02-12

위 문제는 백준 사이트의 알고리즘 11729 문제에 관한 설명입니다.


문제

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다.

각 원판은 반경이 큰 순서대로 쌓여있다.

이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.

  1. 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.

  2. 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.

이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.

아래 그림은 원판이 5개인 경우의 예시이다.

입력

첫째 줄에 첫 번째 장대에 쌓인 원판의 개수 N (1 ≤ N ≤ 20)이 주어진다.

출력

첫째 줄에 옮긴 횟수 K를 출력한다.

두 번째 줄부터 수행 과정을 출력한다.

두 번째 줄부터 K개의 줄에 걸쳐 두 정수 A B를 빈칸을 사이에 두고 출력하는데,

이는 A번째 탑의 가장 위에 있는 원판을 B번째 탑의 가장 위로 옮긴다는 뜻이다.


import java.io.*;

public class Main {
    private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        int n = Integer.parseInt(br.readLine());

        System.out.println((int) Math.pow(2, n) - 1);
        hanoi(n, 1, 2, 3);
        bw.flush();
        br.close();
        bw.close();
    }

    public static void hanoi(int n, int start, int middle, int end) throws IOException {
        if (n == 0)
            return;
        else {
            hanoi(n - 1, start, end, middle);
            bw.write(start + " " + end+"\n");
            hanoi(n - 1, middle, start, end);
        }
    }
}


제가 푼 소스코드입니다.

코드 설명

하노이 탑 문제는 재귀 호출을 이용하여 풀 수 있는 대표적인 문제입니다.

먼저 옮기는 횟수는 원판의 개수가 n 개라고 했을 때 2의n제곱-1 이므로 먼저 출력해주고 시작할 수 있습니다.

장대 세개가 각각 Start, Middle, End 라고 했을 때, n개의 원판을 Start에서 End로 옮기려고 할 때,

규칙에 따라서 맨 밑에 있는 원판이 End에 가장 먼저 놓여야 하는데,

그러기 위해서는 맨 밑 원판을 제외한 나머지 n-1개의 원판을 Middle로 옮겨놓아야 합니다.

그리고 맨 밑 원판을 End로 옮겼으면 아까 옮겨 놓았던 n-1개의 원판을 다시 End로 가져옵니다.

이 때, Start에서 Middle로 옮겨진 n-1개의 원판들도 같은 규칙으로 옮길 것이기 때문에 위의 내용을 그대로 재귀 함수로 구현해주면 됩니다.

즉, n-1개의 원판을 Start에서 Middle로 옮기려고 하는 경우에 대해서 새로 구해주는 것 입니다.

하노이의 탑 이동