하루일문

[백준] 1914번 하노이 탑 (파이썬) 본문

algorithm/baekjoon

[백준] 1914번 하노이 탑 (파이썬)

support_u 2023. 3. 24. 05:29

문제

 

1914번: 하노이 탑

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

www.acmicpc.net

 

코드

def hanoi(n, start, goal, side):
    # 1일 경우(가장 작다) 골로 보내줘
    if n == 1:
        return print(start, goal)
    
    # 아니라면 n-1하면주고 goal, side 위치를 바꿔줘
    # 짝 = goal, side 위치 변경
    hanoi(n-1, start, side, goal)
    
    # 재귀하고 나오면(작은 수가 빠졌다.) 움직일 수 있다
    # 1일 경우와 다른 축에 넣어줘야함
    print(start, goal)
    hanoi(n-1, side, goal, start)

n = int(input())
# 큰 수를 끝으로 옮기는 것 2**n 마지막 -1
# 20초과하는 수도 나와줘야함
print((2**n) - 1)

if n <= 20:
    hanoi(n, 1, 3, 2)

해설

처음에는 리스트로 풀수 있는 줄 알고 도전했으나, 풀지 못해서 해당 알고리즘을 찾아보고 나중에 다시 풀어보았다. 재귀함수를 많이 이해해야지 풀수있는 문제이다.

일단 이동 수는 2의 n승의 -1이다. 자세한 풀이 과정은 하노이의 탑을 검색해보면 이해하기 쉬울 것이다.

 

하노이 탑

하노이 탑이란 1883년 프랑스 수학자 루카스(Lucas)에 의해 고안된 문제인데, 가운데 기둥을 이용해서 왼쪽 기둥에 놓인 크기가 다른 원판을 오른쪽 기둥으로 옮기는 문제였다. 이때 원판은 한번에

terms.naver.com

 

우리가 주의해야 할 점은, goal에서는 판을 빼면 안되기 때문에 goal은 start 점에 있을 수 없는 것과 n == 1이라면 return하여 더 재귀하지 못 하게 해주는 점이다.

코드에서 보기 편하도록 enter를 넣어놨다. n ==1되기 전까지 1번 hanoi에서 재귀가 되고 n==1면 print하고 return하여 그 직전에 재귀로 돌아가서 다시 print를 해주게 하였다. 

재귀를 간단하게 표를 만들어보면 아래와 같다, 빨간 * bold는 print하는 것이고, n이 빨강이 아니라면 return하면서 print된 값이다.

n start goal side
3 1 3 2
2 1 2 3
1 1 3 1
2 1 2 3
1 3 2 1
none
none none none
none none none none
3 1 3 2
2 2 3 1
1 2 1 3