题目
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
假设我们需要将所有圆盘从A移到C上:
情况1:有两个圆盘
此时只须三步:
小盘A–>B
大盘A–>C
小盘B–>C
情况2:有三个盘子
可将最底层大盘上的两个小盘看作整体,此时便与两个盘子的情况1相同:A–>B,A–>C,B–>C
然后需要考虑的是如何将两个小盘整体由A移到B,参考情况1:A–>C,A–>B,C–>B
重点来了:A–>C,A–>B,C–>B和A–>B,A–>C,B–>C,本质上是一样的,实际相当于把B和C换一下位置即可,这一思路的巧妙会在后面的代码中体现出来
情况三:N个盘子
参考情况2,将上层N-1个盘子看作整体,此时A–>B,A–>C,B–>C
如何对于上层N-1个由A–>B又可考虑将其上层N-2个看作整体然后再:A–>C,A–>B,C–>B
对于N-2个由A–>C可考虑将N-3个看作整体然后再:A–>B,A–>C,B–>C
······
此时可发现应用递归解决此题
代码如下:
#include <iostream>
using namespace std;
void hanoi(int num, char a,char b,char c)//输出每一步的操作
{
int count;
if (num==1)
cout << a << "-->" << c << endl;
else
{
hanoi(num-1,a,c,b);//盘数大于1时,便可将上层所有小盘看作整体,第一步便是将该整体由A移到B,如上文所说操作是相同的,实际只需将B和C调换位置即可,因此传参时将将'C'传给b,'B'传给c
cout << a << "-->" << c << endl;//第二步将底层大盘由A移到C
hanoi(num-1,b,a,c);//第三步将小盘整体由B移到C,此时与由A移到C的操作相同,也只需将A和B调换顺序即可,因此传参时将'B'传给a,将'A'传给b
}
}
int main ()
{
int num;
cin >> num;
hanoi(num,'A','B','C');
return 0;
}
整体思路是在学习了网上众多大佬的讲解后明白的,只是在自己用代码实现递归时对传参的操作始终想不明白,最后通过反复思考总算理解了这一操作的巧妙
总结:最重要的是要理解无论A–>C,A–>B,C–>B还是A–>B,A–>C,B–>C以及B–>A,B–>C,A–>C,他们的操作本质上都是是一样的,只需分别把B和C,A和B换一下位置即可,因此便可用上述代码中的巧妙思路实现。