
✅ 결론
원판이 n-1 개일 때 옮길 수 있으면 원판이 n개일 때도 옮길 수 있다.

위가 모두 참이면 원판이 n개일 때도 옮길 수 있다.

void func(int a, int b, int n) // 기둥 a에서 기둥 b로 n개의 원판을 옮기는 역할
if(n == 1) cout << a << ' ' << b << "\n" // 기둥 a에 남아있는 마지막 1개의 원판을 기둥 b로 옮긴다.
func(a, 6-a-b, n-1) // n-1개의 원판을 기둥 a에서 기둥 6-a-b로 옮긴다.
cout << a << ' ' << b << '\n' // n번 원판을 기둥 a에서 기둥 b로 옮긴다.
func(6-a-b, b, n-1) // n-1개의 원판을 기둥 6-a-b에서 기둥 b로 옮긴다.
#include <bits/stdc++.h>
using namespace std;
// 기둥 a에서 기둥 b로 n개의 원판 이동
void hanoi(int a, int b, int n) {
// 기둥 a에 남아있는 원판이 1개일 경우 기둥 b로 옮기고 종료
if (n == 1) {
cout << a << ' ' << b << "\n";
return;
}
// 1. 기둥 a에 있는 n-1개의 원판을 보조 기둥(6 - a - b)으로 이동
hanoi(a, 6 - a - b, n - 1);
// 2. 가장 큰 n번째 원판을 기둥 a에서 기둥 b로 이동
cout << a << ' ' << b << "\n";
// 3. 보조 기둥에 있던 n-1개의 원판을 기둥 b로 이동
hanoi(6 - a - b, b, n - 1);
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
cout << (1 << n) - 1 << "\n"; // 이동 횟수 출력
hanoi(1, 3, n);
}
int a = 3; // 0000 0011
int b = a << 1; // 0000 0110 -> b는 6 (3 * 2^1)
int c = 12; // 0000 1100
int d = c >> 1; // 0000 0110 -> d는 6 (12 / 2^1)
<< : 비트를 왼쪽으로 이동시키는 연산자, 2의 n제곱만큼 곱하기와 같다.>> : 비트를 오른쪽으로 이동시키는 연산자, 2의 n제곱만큼 나누기와 같다.
- 원판 k개를 옮길 경우 : 총 a번 이동해야 한다.
- 원판 k+1개를 옮길 경우 :
k개의 원판을 중간 기둥으로 옮길 때, a번+k+1번째 원판을 최종 기둥으로 옮길 때, 1번+k개의 원판을 최종 기둥으로 옮길 때, a번= 총2*a + 1번 이동해야 한다.
k가 1일 때 최소 이동 횟수는 1번 , 즉 초항이 1이므로 최소 이동 횟수의 일반항은 2^k - 1 가 된다.
