汉诺塔游戏就是有三根柱子A,B,C,在A柱子上从下往上按照大小顺序摞着N片圆盘。需要把圆盘从下面开始按大小顺序重新摆放在C柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔问题的解决总体上可以归结为以下三个步骤:
(1)将A上N-1个圆盘借助C先移动到B上;
(2)将A上剩下的最大的圆盘移动到C上;
(3)将B上的N-1个圆盘借助A移动到A上。
这就是一个典型的迭代过程。
C++实现过程如下:
#include <iostream>
using namespace std;
void hanoi(int n,char A,char B,char C);
void main()
{
/* 对hanoi函数的声明 */
int m;
cout << "input the number of diskes:";
cin >> m;
cout << "The step to moveing " << m << " diskes:\n";
hanoi(m, 'A', 'B', 'C');
}
void hanoi(int n, char A, char B, char C)
/* 定义hanoi函数, 将n个盘从A座借助B座,移到C座 */
{
void move(char x, char y); /* 对move函数的声明 */
if( n==1 )
{
move(A, C);
}
else
{
hanoi(n-1, A, C, B);
move(A,C);
hanoi(n-1,B,A,C);
}
}
void move(char x, char y) /* 定义move函数 */
{
cout << x << "-->" << y << "\n";
}
扩展问题:
求完成游戏所需要的移动的次数
我们可以知道,(1)与(3)操作道理是相似的。不去管那个最大盘子,(1)是以C为中转站,(3)是以A为中转站。因此两者所需的移动次数应当是相等的。这意味着我们只要计算出其中一者的移动次数,然而乘以2,在加上“移动最大盘子”的那1次,就是这场游戏的总移动次数了。
用数学语言表达,假设(1)“将N-1个盘子从A移动到B”所需次数为Hn-1,总移动次数为Hn,那么可以得出的关系就是:Hn=Hn-1 x 2 + 1.
于是,Hn=Hn-1 x 2 + 1 这个公式,就可以一直迭代……H3=7,H2=3,H1=1。
最后,数学归纳法证明通项公式:Hn = 2^n - 1