汉诺塔问题描述:
有三个柱子,其中一个柱子上从下往上放着直径依次增大的圆盘,要求把这些圆盘移动到另一个圆盘,移动的过程中不能使小的圆盘在大的圆盘下面,问如何移动。
分析:
递归的经典问题,不能太拘泥于细节的实现。
首先,来看倒数第二个局面,假设1,2,3柱,最大的圆盘在1柱,1到n-1个圆盘在3柱,现在只需要把1到n-1个圆盘移动到1柱,由于n的直径大于前n - 1个圆盘,那么1柱实际既可以看成空柱,因为我们不移动第n个,所以它的存在对结果不影响,所以现在就只剩移动n-1个圆盘的工作量。
这就跟移动n个圆盘的问题结构是一样的,只不过规模减小了1,所以,这就是递归的子问题。
我们每一次的移动,就只需要考虑把我们的目标柱子和中转柱子以及起始柱子的位置互换一下就ok了。
总结:
分析递归的问题,一般是寻找与最大的问题结构相同的子问题,然后逐渐减小问题规模,达到最终解决问题的目的。
代码:
1 #include <stdio.h> 2 3 int cnt = 0; 4 5 void move(char from,char to) 6 { 7 printf("%d %c -> %c\n",++cnt,from,to); 8 } 9 10 void hanota(int n,char from,char trans,char to) 11 { 12 if (n == 1) move(from,to); 13 else 14 { 15 hanota(n-1,from,to,trans); 16 move(from,to); 17 hanota(n-1,trans,from,to); 18 } 19 } 20 21 int main() 22 { 23 int n; 24 25 scanf("%d",&n); 26 27 hanota(n,'A','B','C'); 28 29 printf("Total times : %d\n",cnt); 30 31 return 0; 32 }