漢諾塔問題描述
假設有3個分別命名爲A,B,C的塔座,在塔座A上插有n個直徑大小各不相同,依小從大編號爲1,2,........,n的圓盤。現要求將塔座A上的n個圓盤移至塔座C上,並仍按同樣的順序疊排,圓盤移動時必須遵守下列規則:
- 每次只能移動一個圓盤;
- 圓盤可以插在A,B和C中的任一塔座上;
- 任何時候都不能將一個較大的圓盤壓在較小圓盤上;
三個圓盤移動方法
所有的移動方法都是按照上圖進行移動的
可以把上面看成七步,無論有多少圓盤,都是按照這七步進行。(等於實際代碼3步實現的分解方法)
下面分析當圓盤數大於3時情況
總體思路(個人理解)
- 每次都將上面(n-2)個圓盤看作一個整體A。然後底層兩個看作B,C;
- 所以此時移動一次A的位置,即把整個A的整體移動
下面以4個圓盤爲例(畫圖的話太麻煩了,所以用運行截圖代替)
若數量過多,都依舊按照這個方法進行。
右圖(a)(b)(c)(d)即相當於七步中的第一步,將(n-2)看作一個整體。
方法(相當於基礎7步的濃縮):
- 用3柱做過渡,將1柱上的(n-1)個盤子移動到2柱;
- 將1柱上最後一個盤子移動到3柱上
- 用1柱做過渡,將2柱上的(n-1)個盤子移動到3柱上
代碼:
#include<iostream>
using namespace std;
int m = 0; //移動的第n步
void move(char A, int n, char C)
{
cout << ++m << "," << n << "," << A << "," << C << endl;
}
void Hanoi(int n, char A, char B, char C)
{
if (n == 1)
{
move(A, 1, C); //結束
}
else
{
Hanoi(n - 1, A, C, B); //用3柱做過渡,將1柱上的(n-1)個盤子移動到2柱;
move(A, n, C); //將1柱上最後一個盤子移動到3柱上
Hanoi(n - 1, B, A, C); //用1柱做過渡,將2柱上的(n-1)個盤子移動到3柱上
}
}
int main()
{
Hanoi(4, 'A', 'B','C'); //此處A,B,C代表1,2,3柱。
system("pause");
}