티스토리 뷰

Algorithm/BOJ

1914 하노이 탑

henry1214 2018. 2. 9. 17:20

https://www.acmicpc.net/problem/1914



하노이 탑은 세 개의 기둥으로 이루어진 퍼즐이다. 첫번째 기둥에 N개의 원판들의 쌓여 있고 두 가지 규칙을 지키면서 세번째 기둥으로 옮겨야 한다. 작은 원판은 항상 큰 원판 위에 있어야 하고 한번에 하나씩만 옮길 수 있다. 이를 재귀 호출로 구현할 수 있다. go(n,x,y)를 n개의 원판을 x 기둥에서 y 기둥으로 옮기는 함수로 정의한다. 그러면 먼저 제일 아래 원판을 제외한 n-1개의 원판을 x와 y가 아닌 기둥으로 옮기고 나서 제일 아래 원판을 y로 옮긴다. 마지막으로 임시로 옮겨놓았던 n-1개의 원판을 y위에 쌓는다. 적절히 재귀 함수를 설계하면 모든 과정이 저절로 이루어짐을 알 수 있다.


이 때 점화식을 유도할 수 있다. n-1개의 원판을 두번 옮기고 마지막에 원판 하나를 옮기므로



이 문제에서는 최대 N=100 이므로 일반적인 자료형으로는 구할 수 없다. string으로 큰 수 연산을 구현하였다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
 
void go(int n,int x,int y)
{
    if(n==0return;
    go(n-1,x,6-x-y);
    cout<<x<<' '<<y<<'\n';
    go(n-1,6-x-y,y);
}
 
void cnt(int n)
{
    string s="1";
    while(n--)
    {
        int up=0;
        for(int i=0;i<s.size();i++)
        {
            int d=(s[i]-'0')*2+up;
            if(d<10) s[i]=d+'0',up=0;
            else s[i]=d%10+'0',up=d/10;
        }
        if(up) s+=up+'0';
    }
    if(s[0]!='0') s[0]--;
    else
    {
        s[0]='9';
        for(int i=1;i<s.size();i++)
            if(s[i]!='0') { s[i]--break; }
    }
    reverse(s.begin(),s.end());
    cout<<s<<'\n';
}
 
int main()
{
    int n;
    cin>>n;
    cnt(n);
    if(n<=20) go(n,1,3);
    return 0;
}
cs




'Algorithm > BOJ' 카테고리의 다른 글

1021 회전하는 큐  (0) 2018.02.11
2448 별찍기 - 11  (0) 2018.02.11
9020 골드바흐의 추측  (0) 2018.02.09
11559 Puyo Puyo  (0) 2018.02.09
5635 생일  (0) 2018.02.09
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday