相信大家已经知道汉诺塔问题了,这里就不再赘述了。汉诺塔这一问题在去年我认为自己搞清楚了,但是现在回头看这一问题,发现并不是那么清楚。经典的题目果然是经典题,之前之搞清楚了它是怎么实现的,原理好像懂了,但肯定是没有掌握。现在又学习了一下,感觉弄懂了,故写下此篇。
首先我们需要明白一个前提,最大的盘子不会影响其他盘子的移动。且对于问题,我们需要按顺序把盘子从大到小移到C塔上。如:有n个盘子时,步骤为先把最大的移到C上,再把第二大的盘子移到C上,第三大移到C上……
当n=1时,做法A->C;
当n=2时,做法A->B,A->C,B->C。这一步可以这样理解,当有两个盘子时我们需要先把第二大的盘子移到B上,再把最大的盘子移到C上,最后把B上的移到C上。也就是先进行一步F(1,A->B),在进行F(1,A->C),最后F(1,B->C),其中F(n,x->y)表示把x上的n个盘子移到y。
当n=3时,我们需要把最大的盘子移到C上,那么我们应该把A上的2个盘子移到B上,再把A上最大的移到C上,最后把B上的2个盘子移到C上即可。也就是F(2,A->B)+F(1,A->C)+F(2,B->C)。此时规模转变为n=2的情况。
……
当n=n时,根据之前所说,我们需要把A上n-1个盘子移到B上,再把最大的盘子(即A上最后一个盘子)移到C上,最后把B上n-1个盘子移到C上就完成了。也就是F(n-1,A->B)+F(1,A->C)+F(n-1,B->C)。
需要注意的是:F(n-1,A->B)=F(n-2,A->C)+F(1,A->B)+F(n-2,C->B)。
即完成把大问题n,化为小一点的问题n-1,再小一点的n-2,……,直到化为jian简单的1。
代码如下:
#include<iostream> using namespace std; int fun(int n,char start,char mid,char end) { if (n == 1) cout << start << "->" << end<<endl; else return fun(n - 1, start, end, mid) + fun(1, start, mid, end) + fun(n - 1, mid, start, end); } int main() { int n; char start = 'A', mid = 'B', end = 'C'; cin >> n; fun(n,start,mid,end); system("pause"); return 0; }