关于汉诺塔问题的最终解决

关于汉诺塔问题的最终解决,第1张

关于汉诺塔问题的最终解决,第2张

提出的问题:大约在19世纪末,欧洲的商店里出售一种智力玩具。一个铜板上有三根杆子,最左边的杆子从上到下串了一个64个圆盘的塔。目的是把最左边一栏的盘子全部移到右边一栏,前提是一次只能移动一个盘子,不允许把大盘子放在小盘子上。

*问题分析与算法设计
这是一个新问题,几乎所有教材都有这个问题。由于条件是一次只能移动一个磁盘,不允许将大磁盘放在小磁盘上,所以64个磁盘的移动次数是:
18446744073709551615
这是一个天文数字。如果有可能每微秒计算(而不是输出)一步棋,那么我们只能找到问题的解,求解N值很小的河内塔,而用计算机很难求解64层的河内塔。

分析问题,找出正确的算法来移动盘子。

首先考虑A杠下面的盘子而不是杠上面的盘子,那么任务就变成了:
*把上面的63个盘子移到B杠上;
*将A栏上剩余的板移到C栏上;
*将B栏上的所有盘子移到C栏上。

要继续这个过程,首先要完成移动63板、62板、61板等工作。

为了更清楚地描述该算法,可以定义函数movedisc(n,a,b,c)。该功能的作用是:通过C杆将N块板从A杆移动到B杆。使得移动N块板的工作可以按照以下过程进行:
1) movedisc(n-1,a,c,b);
2)将一个盘子从A移到B;
3) movedisc(n-1,c,b,a);
重复上述过程,直到所有板都移动到位。

*程序与程序注释
#include
void movedisc(unsigned n,char fromneedle,char toneedle,char usingneedle);
int i=0;
void main()
{
unsigned n;
printf("please enter the number of disc:");
scanf("%d",&n); /*输入N值*/
printf("\tneedle:\ta\t b\t c\n");
movedisc(n,'a','c','b'); /*从A上借助B将N个盘子移动到C上*/
printf("\t Total: %d\n",i);
}
void movedisc(unsigned n,char fromneedle,char toneedle,char usingneedle)
{
if(n>0)
{
movedisc(n-1,fromneedle,usingneedle,toneedle);
/*从fromneedle上借助toneedle将N-1个盘子移动到usingneedle上*/
++i;
switch(fromneedle) /*将fromneedle 上的一个盘子移到toneedle上*/
{
case 'a': switch(toneedle)
{
case 'b': printf("\t[%d]:\t%2d.........>%2d\n",i,n,n);
break;
case 'c': printf("\t[%d]:\t%2d...............>%2d\n",i,n,n);
break;
}
break;
case 'b': switch(toneedle)
{
case 'a': printf("\t[%d]:\t%2d%2d\n",i,n,n);
break;
case 'c': printf("\t[%d]:\t %2d........>%2d\n",i,n,n);
break;
}
break;
case 'c': switch(toneedle)
{
case 'a': printf("\t[%d]:\t%2d

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 关于汉诺塔问题的最终解决

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情