简介
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
分析
因为题目要求我们每次移动后的结果为:在每一杆上的金盘都要保证是从小到大一次排序的。
由此可知,我们要把A杆中的金盘(共n个)全部移到C杆,且保持原来的金盘大小顺序不变。即完成移动之时,A杆中最大的盘子(第n个)必定在C杆的最下层,这就意味着我们想要达到这个目的必须将其他的(n-1)的金盘先从A杆移动到B杆,这时才能移动最大的这个金盘(保证A杆中只有最大的这个金盘且C杆上没有金盘)到C杆上。
第一次完整移动达成的目的
由上,我们第二步则需要将倒数第二大的金盘移动到C杆上,这就要求我们要先将除目的金盘外都先经由C移动到A上,这时我们才能移动倒数第二大的金盘到C上。
不断完成上述步骤,每次的结果都是要先经过一个中转杆移动(n-1)个金盘,然后将第n个金盘移动到C上。
源码实现
#include<stdio.h>
//汉诺塔问题
int hanoi(char A, char B, char C ,int n)
{
if (n == 1)//只有一层时直接移动,只走一步
{
printf("%c-> %c\n", A, C);
return 1;
}
else
{
hanoi(A, C, B, n - 1);
printf("%c-> %c\n", A, C);
hanoi(B, A, C, n - 1);
return 2 * hanoi(A, C, B, n-1) +1;//移动的步数等于(n-1)的两次中转次数加最后一次的移动
}
}
int main()
{
int n = 0;
printf("请输入汉诺塔层数\n");
scanf("%d", &n);
char A = 'A', B = 'B', C = 'C';
int num = hanoi(A, B, C, n);
printf("走%d步\n", num);
return 0;
}
预期结果展示