簡單的漢諾塔問題【遞迴】
阿新 • • 發佈:2018-11-25
題目連結:http://bailian.openjudge.cn/practice/4147/
問題描述:
有三根杆子A,B,C。A杆上有N個(N>1)穿孔圓盤,盤的尺寸由下到上依次變小。要求按下列規則將所有圓盤移至C杆: 每次只能移動一個圓盤; 大盤不能疊在小盤上面。 提示:可將圓盤臨時置於B杆,也可將從A杆移出的圓盤重新移回A杆,但都必須遵循上述兩條規則。
問:如何移?最少要移動多少次?
漢諾塔示意圖如下:
三個盤的移動:
輸入:
輸入為一個整數後面跟三個單字元字串。
整數為盤子的數目,後三個字元表示三個杆子的編號。
輸出:
輸出每一步移動盤子的記錄。一次移動一行。
每次移動的記錄為例如3:a->b 的形式,即把編號為3的盤子從a杆移至b杆。
我們約定圓盤從小到大編號為1, 2, ...n。即最上面那個最小的圓盤編號為1,最下面最大的圓盤編號為n。
樣例輸入:
3 a b c
樣例輸出:
1:a->c 2:a->b 1:c->b 3:a->c 1:b->a 2:b->c 1:a->c
解題思路:
把前n-1個盤放到B杆上,再把第n個盤放到第C個杆上,最後把前n-1個盤放到第C個杆上,即可完成任務。
那麼如何把前n-1個盤放到B杆上呢?
我們可以通過C杆,將前n-2個盤放到C杆上,再把第n-1個盤放到B杆上,最後把前n-2個盤放到B杆上。
以此類推對前n-3、n-4、n-5 ··· 個盤的操作,當只剩一個盤時,直接將盤放到該放的杆上即可。
程式碼如下:
#include <iostream> #include <cstdlib> using namespace std; void rec(int n,int base,char t1,char t2,char t3) // 此次要移動多少個盤;最底層盤的編號;所在杆、中轉杆、目的杆 { if(n == 1) { // 只需一動一個盤子 cout << base << ":" << t1 << "->" << t3 <<endl; // 將盤從t1直接放到t3 return; // 遞迴終止 } rec(n-1,base-1,t1,t3,t2); // 將前n-1個盤放到t2 cout << base << ":" << t1 << "->" << t3 << endl; // 直接將第n個盤放到t3 rec(n-1,base-1,t2,t1,t3); // 最後將前n-1個盤放到t3 } int main() { int num; // 所需移動的盤數 char tower1,tower2,tower3; // 所在杆、中轉杆、目的杆 cin >> num >> tower1 >> tower2 >>tower3; rec(num,num,tower1,tower2,tower3); return 0; }