(n階Hanoi塔問題)假設有三個分別命名爲A、B、C的塔座,在塔座A上插有n(n<20)個直徑大小各不相同、依小到大編號爲1,2,…,n的圓盤。現要求將A軸上的n個圓盤移至塔座C上並仍按同樣順序疊排,圓盤移動時必須遵循下列規則: 1)每次只能移動一個圓盤; 2)圓盤可以插在A、B、C中的任一塔座上; 3)任何時刻都不能將一個較大的圓盤壓在較小的圓盤之上。 請通過編程來打印出移動的步驟.
Hanoi問題絕對是一個理解遞歸的好題,對一個將N個圓盤從A移動到C的問題,我們可以將它分解成三步
- 將其上的N-1個圓盤從A移動到B。
- 將第N個圓盤從A移動到C。
- 將B上的N-1個圓盤移動到C。
每次移動都有一個起點S,一個終點T,還有一箇中介M,另外還有想要移動的盤子的數目cnt,當需要移動的數目爲1時,我們就可以打印移動的方法。寫成程序就是下面這樣
//將cnt個圓盤從S盤經過M移動到T
void hanoi(char S, char T, char M, ll cnt) {
if (cnt == 1)
pprint(S, T);
else {
hanoi(S, M, T, cnt - 1);//把上面cnt-1個硬盤從S經過T移動到M
hanoi(S, T, M, 1);//把最底下的1個硬盤移動到T
hanoi(M, T, S, cnt - 1);//把移動到M上的cnt-1個硬盤通過S移到終點T
}
}
然後就是需要注意路徑的打印五個一組,使用一個全局變量進行監控即可
#define ll int
#define inf 0x3ffffff
#define vec vector<ll>
ll tot = 0;
void pprint(char s, char t) {
if (tot == 5)printf("\n"), tot = 0;
printf("%c-->%c ", s, t); tot++;
}
//將cnt個圓盤從S盤經過M移動到T
void hanoi(char S, char T, char M, ll cnt) {
if (cnt == 1)
pprint(S, T);
else {
hanoi(S, M, T, cnt - 1);//把上面cnt-1個硬盤從S經過T移動到M
hanoi(S, T, M, 1);//把最底下的1個硬盤移動到T
hanoi(M, T, S, cnt - 1);//把移動到M上的cnt-1個硬盤通過S移到終點T
}
}
int main() {
ll n;
while (cin >> n && n) {
hanoi('A', 'C', 'B', n);
printf("\n"); tot = 0;
}
}