一、什么是汉诺塔:
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
二:解决思路
1.分析:
对于这样一个问题,任何人都不可能直接写出移动盘子的每一步,但我们可以利用下面的方法来解决。设移动盘子数为n,为了将这n个盘子从A杆移动到C杆,可以做以下三步:
(1)以C盘为中介,从A杆将1至n-1号盘移至B杆;
(2)将A杆中剩下的第n号盘移至C杆;
(3)以A杆为中介;从B杆将1至n-1号盘移至C杆。
2.样例模拟:
(😆读图顺序从左到右,从上到下😆)
①当罗盘数n=1时:
💨💨💨这种情况我们直接就能将A杆上的罗盘移动到C上:A->C。💨💨💨💨💨💨💨💨💨
②当罗盘数n=2时:
💨💨💨由上图我们知道罗盘挪动的过程为:A->B,A->C,B->C。💨💨💨💨💨💨💨💨💨
③当罗盘数n=3时:
💨💨由上图我们知道罗盘挪动的过程为:A->C,A->B,C->B,A->C,B->A,B->C,A->C。
3.移动步数:
对于以上三个案例你是否冥冥之中能够察觉到随着罗盘数量增多,我们将A中罗盘移动到C的步骤是随着一定的规律逐渐增加的,这里我也不卖关子啦,移动步数,所以对于汉诺塔这个问题的样例模拟到n=3次数就比较哆啦,感兴趣的小伙伴可以自行动手去尝试一下,但建议不要太多哦🌞!
三、代码实现:
1.代码思路
由上述分析我们可以将汉诺塔复杂的问题简单化,汉诺塔的问题实质上就是将原地点(A)处的罗盘通过B或者A为中转站将罗盘全部原封不动得转移到C上。而在这个过程中,我们始终都是将最开始A上除开最底下最大的圆盘之外的n-1个圆盘先转移到B,然后把A中剩下最大的罗盘直接放到C上(A->C),将最大的处理后再处理第n-1个,再第n-2个......就像在剥洋葱一样,一层一层的,所以我们这里自然联想到递归处理。
2.递归实现
#include <stdio.h>
void Hanoi(int n,char pos1,char pos2,char pos3)
{
if (n == 1)
{
printf("%c -> %c\n", pos1, pos3); //A->C
}
else
{
Hanoi(n - 1, pos1, pos3, pos2); //将A中除开最大的罗盘上的n-1个通过C为中介全部移动到B
printf("%c -> %c\t",pos1,pos2);
Hanoi(n - 1, pos2, pos1, pos3); //将B中的全部罗盘通过A为中介全部移动到C
}
}
int main()
{
int n = 0; //罗盘数
scanf_s("%d", &n);
char pos1 = 'A';
char pos2 = 'B';
char pos3 = 'C';
Hanoi(n, pos1, pos2, pos3);
}