一、题目描述
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上上。(摘自360百科)
二、求解思路
1、看到这个问题,我们可以总结出三点有用的信息
a.只能移动最顶端的盘子
b.一次只能移动一个盘子
c.移动过程一定保持大圆盘在下小圆盘在上
2、共有A、B、C三个杆子
如果只有一个盘子,直接将目标盘子从A<--->C
如果有两个盘子,将1从A<--->B,将2从A<--->C
如果是三个盘子呢??经过思考我们不难得出第1步将A<----->C,第2步将A<----->B,第3步将C<----->B,第4步将A<----->C,第5步将B<----->A,第6步将B<----->C,第7步将A<----->C
从这里我们好像看到了递归的影子,递归的思想就是“将大事化小”,我们移动三个盘子的时候,是以C为媒介将1,2两个盘子移到B上,再将3号盘子由A移向C。所以我们每次只要分离出最大的盘子,再将最大的盘子移动到目标杆。
假如有n个盘子,我们应该把n-1个盘子移走,那么如何做呢?我们应该把以C为过渡柱将n-1个盘子暂时放在B柱子上,再将第n个盘子从A<---->C,接下来又是同样的算法,暂存在B柱子上的n-1个盘子以C柱为媒介暂存n-2个盘子在A柱子上,再将B柱子上的最大的盘子移动到C柱子上。
递归的两个条件:
①限制条件:n=1时不再递归
②每次移动时当前最大的盘子已经移到目标杆子上去了,数量就减一,越来越接近这个限制条件
三、附上代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int i = 0;
void move(int n, char from, char to)
{
i++;
printf("第%d步将%d号盘子%c<----->%c\n",i, n, from, to);
}
Hanoi(int n, char A, char B, char C)
{
if (n == 1)
{
move(n, A, C);
}
else
{
Hanoi(n - 1, A, C, B);
move(n, A, C);
Hanoi(n - 1, B, A, C);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
Hanoi(n, 'A', 'B', 'C');
printf("共%d步\n", i);
return 0;
}
递归还是很晦涩,我只是讨论了前几种情况,寻找其中的规律。继续学习理解再来补充。如果写的有错误或者有什么建议可以告诉我谢谢,及时修正。。
(* ̄︶ ̄)