1. 程式人生 > >簡單的漢諾塔問題【遞迴】

簡單的漢諾塔問題【遞迴】

題目連結: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;
}