题目 2056: 汉诺塔
时间限制: 1Sec 内存限制: 128MB 提交: 585 解决: 317
题目描述
汉诺塔是一种古老的游戏。
一共3个柱子,标号为1,2,3
1号柱子有从大到小一共n个盘子。
每次移动最上方的一个盘子,可以移动到其他的柱子。
任何一个盘子,都不能叠在比它更小的盘子的上方。
请把盘子从1号柱子,全部移动到3号柱子。
起始:
移动到这样:
现在,给出了n个盘子,请你描述一下用最短次数移动的过程。
输入
一个数,n,表示盘子的数量(n<=10)
输出
输出若干行。
每次操作,输出一行。输出“Move x from x to x”的格式。
最小盘子的编号为1,最大盘子的编号为n。
样例输入
4
样例输出
Move 1 from 1 to 2
Move 2 from 1 to 3
Move 1 from 2 to 3
Move 3 from 1 to 2
Move 1 from 3 to 1
Move 2 from 3 to 2
Move 1 from 1 to 2
Move 4 from 1 to 3
Move 1 from 2 to 3
Move 2 from 2 to 1
Move 1 from 3 to 1
Move 3 from 2 to 3
Move 1 from 1 to 2
Move 2 from 1 to 3
Move 1 from 2 to 3
解析:
汉诺塔是一道典型的递归题,通过对它的学习我们也能对递归有一个更加深刻的了解。那么,为了方便我们理解,不妨我们可以将算法这样解释:
美女冯需要按照汉诺塔的规则将塔1上n个盘片转移到塔3上,但是她力气不够,最多只能将第n块从塔1转移到塔3,因此她让她的丈夫帅哥李把他们n-1孩子们叫来帮忙把前面n-1块从塔1挪到塔2,等妈妈将第n块挪到塔3上后再将这n-1块挪到塔3。
然而,由于一次只能挪动一个盘子,孩子们也进行了明确的分工,老大负责第n-1片从塔1挪到塔2,其他人负责将前n-2片先挪到塔3,等老大将第n-1块挪到塔2后再将这n-1块挪到塔2…
由此我们便找到了递归的规律:
我们每次将x个盘片从a处移动到c处,由于小盘片压大盘片的规则总需要先将盘片分为(第x片,前x-1片)两组,然后上面的x-1个盘片在b处临时存放,用这个规律递归下去第n-1个小孩只需要挪动最上面的盘片。
C语言代码:
#include<stdio.h>
void hannoi(int n,char a,char b,char c)
{
if(n==1)
printf("Move %d from %c to %c\n",n,a,c);//冯美女开心极了,她只需要搬动一个盘片即可
else
{
hannoi(n-1,a,c,b);//先将前n-1片临时放到b处
printf("Move %d from %c to %c\n",n,a,c);//将第n片从a处挪动到c处并打印
hannoi(n-1,b,a,c);//前n-1片从临时位挪到c位
}
}
int main()
{
int n;
scanf("%d",&n);
hannoi(n,'1','2','3');//递归调用,我们的任务是将n个盘片从塔1挪到塔3
return 0;
}