[백준] 11729_하노이탑 이동순서_C++

forunhyuck·2023년 7월 29일

📌 문제

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.

한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.

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


📥 입력

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


📤 출력

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

두 번째 줄부터 수행 과정을 출력한다. 두 번째 줄부터 K개의 줄에 걸쳐 두 정수 A B를 빈칸을 사이에 두고 출력하는데, 이는 A번째 탑의 가장 위에 있는 원판을 B번째 탑의 가장 위로 옮긴다는 뜻이다.


💻 해결책

// 3번 장대를 거쳐 2번 장대로 옮긴다.
// 제일 큰 원판을 3번으로
// 나머지 원판을 1번을 거쳐 3번으로 이동한다.

#include<iostream>
#include<cmath>
using namespace std;
// 시작,목표,보조, 갯수
void hanoi(int start,int end,int assist,int n){
    if(n==1){
        cout<<start<<" "<<end<<'\n';
    }else{
        hanoi(start,assist,end,n-1);
        cout<<start<<" "<<end<<"\n";
        hanoi(assist,end,start,n-1);
    }
}

int main(){
    int N;
    cin>>N;
    cout<<(int)pow(2,N)-1<<endl;
    hanoi(1,3,2,N);
}

n개의 원판을 첫번째 막대에서 세번째 막대로 이동시키는 방법은
n-1개의 원판을 첫번째에서 두번째로 이동한다.
그리고 마지막 원판을 첫번째에서 세번째로 이동한다.
n-1개의 원판을 첫번째를 거쳐서 세번째로 이동한다.

또한, 횟수를 출력해야 하므로 하노이탑의 최소 이동횟수는 2^n-1이다.
이것을 pow 함수를 써야한다. -> #include 사용해야한다.
pow(2,num)을 사용한다면 double형을 활용하는 pow 특성상 입력 최댓값인 20이 입력되면 오차가 생겨서 답이 틀릴수 있다.
따라서 (int)pow(2,num) 을 써야한다.

profile
Just do it

1개의 댓글

comment-user-thumbnail
2023년 7월 29일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기