1、问题描述:有a,b,c三个底座,上面可以放盘子。初始时,a座上有n个盘子,这些盘子大小各不相同,大盘子在上,小盘子在下,依次排列。要求将a座上的n个盘子移动到c座上,每次只能移动一个,且移动过程中要求保持小盘子在上,大盘子在下,可借助b实现移动。现要求给出移动的步骤。
2、问题分析:本问题要求程序给出盘子的移动过程,如果n足够大,而我们陷入到盘子的具体移动过程中,这将非常麻烦(其实在n>3该过程就已经很烦琐了),所以本问题的最佳解决方法是递归(其实汉诺塔问题是递归算法的经典),即把具体的移动过程交给计算机,我们只需总结出其移动原理,其如下:
- 先将a上的n-1个盘子借助c移动到b
- 再将a上的最下方的盘子移动至c
- 最后将b上的n-1个盘子借助a移至c
#include<cstdio>
int main()
{
int n;
scanf("%d",&n);
void Move(char ,char);
void Hanoi(int n,char A,char B,char C);
Hanoi(n,'a','b','c');
return 0;
}
void Move(char chSour,char chDest)
{
printf("%c-->%c\n",chSour,chDest);
}
void Hanoi(int n,char A,char B,char C)
{
if(n==1)Move(A,C);
else{
Hanoi(n-1,A,C,B);//先将a上的n-1个盘子借助c移至到b
Move(A,C); //再将a座最下方的盘子移至c
Hanoi(n-1,B,A,C); //最后将b上n-1个盘子借助a移至c
}
}
4、递归算法的特点:
- 递归即自己调用自己
- 每次调用后在规模上都有所减小(如本问题中又n到n-1,到n-2,直到1)
- 相邻两次之间有联系,前一次为下一次做准备
- 在规模足够小时,必须给出解答而不在进行递归(如本问题中当n=1时,给出解答 Move(A , C); )
- 必须有结束条件(如本问题中n=1)
结构清晰,可读性强,容易用数学规纳法证明!