七层的汉诺塔游戏最少几步完成?

七层的汉诺塔游戏最少几步完成?,第1张

七层的汉诺塔游戏最少需要127步。

其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步 *** 作就可以了。

首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;

若n为奇数,按顺时针方向依次摆放 A C B。

⑴按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。

⑵接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较大的圆盘。芹烂这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。

⑶反复进行⑴⑵ *** 作,最后就能按规定完成汉诺塔的移动。

所以结果非常简单,就是按照移动规则向一个方向移动金片:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C。汉诺塔问题也是程序设计中的经典递归问题。

扩展资料

汉诺塔是一个关于世界末日的古老的传说,在世界嫌答漏中心贝拿勒斯(在印度北部)的圣庙里,安放着一个汉诺塔,有64块金片。梵天在创造世界的时留下的。由值班的僧侣法则日夜不停地搬运。当搬运完毕时举知,也就是世界的末日。

汉诺塔是源于印度一个古老传说的益智游戏。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。随着盘数的增加,需要移动的次数也会越来越多,问题就变得越来越复杂,一个不小心就可能出错。

汉诺塔还有个最关键的问题就是第一步的第一小步是将顶层圆盘挪至辅助柱还是还是目标柱的问题。说它关键,是因为一步错,步步错。第一步走错了,后面再怎么走,也不会走对。

经过推理与分析,找到了问题的答案:若塔层数为奇数,顶层圆盘应首先放在目标柱;若是偶数,则放在辅助柱。

递归算法是我前些天写的,非递归是刚才找的,里面含递归和非递归。\x0d\x0a递归算法:\x0d\x0a#include \x0d\x0a//递归求汉诺塔问题\x0d\x0avoid hanoi(int n, char A, char B, char C, int *time)\x0d\x0a{\x0d\x0aif (n>=1)\x0d\x0a{\x0d\x0a hanoi(n-1, A, C, B, time)\x0d\x0a move(A, C)\x0d\x0a (*time)++\x0d\x0a hanoi(n-1, B, A, C, time)\x0d\x0a}\x0d\x0a}\x0d\x0a//打印出每一步的路径\x0d\x0avoid move(char a, char c)\x0d\x0a{\x0d\x0aprintf(" %c-->%c\n", a, c)\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint n, time = 0\x0d\x0aprintf("请输入汉诺塔的盘数:")\x0d\x0ascanf("%d", &n)\x0d\x0aprintf("%d个盘的汉诺塔移动方法是:", n)\x0d\x0aprintf("\n")\x0d\x0ahanoi(n, 'A', 'B', 'C', &time)\x0d\x0aprintf("移动了%d次\n", time)\x0d\x0asystem("pause")\x0d\x0areturn 0\x0d\x0a}\x0d\x0a\x0d\x0a非递裤做归算法:\x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXSTACK 10 /* 栈的最大深度 */\x0d\x0a\x0d\x0aint c = 1/* 一个全局变量,表示目前移动的步数 */\x0d\x0a\x0d\x0astruct hanoi { /* 存储汉诺塔的结构,包括盘的数目和三个盘的名称 */\x0d\x0aint n\x0d\x0achar x, y, z\x0d\x0a}\x0d\x0a\x0d\x0avoid move(char x, int n, char y) /* 移动函数,表示把某个盘从某根针移动到另一根针 */\x0d\x0a{\x0d\x0aprintf("%d->%d from %c ->%c\n", c++, n, x, y)\x0d\x0a}\x0d\x0a\x0d\x0avoid hanoi(int n, char x, char y, char z) /* 汉诺塔的递归算法 */\x0d\x0a{\x0d\x0aif (1 == n)\x0d\x0amove(x, 1, z)\x0d\x0aelse {\x0d\x0ahanoi(n - 1, x, z, y)\x0d\x0amove(x, n, z)\x0d\x0ahanoi(n - 1, y, x, z)\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0avoid push(struct hanoi *p, int top, char x, char y, char z,int n)\x0d\x0a{\x0d\x0ap[top+1].n = n - 1\x0d\x0ap[top+1].x = x\x0d\x0ap[top+1].y = y\x0d\x0ap[top+1].z = z\x0d\x0a}\x0d\x0a\x0d\x0avoid unreverse_hanoi(struct hanoi *p) /* 汉诺塔的非递归算法 */\x0d\x0a{\x0d\x0aint top = 0\x0d\x0a\x0d\x0awhile (top >胡闷衡= 0) {\x0d\x0awhile (p[top].n >1) { /* 向左走到尽头 */\x0d\x0a push(p, top, p[top].x, p[top].z, p[top].y, p[top].n)\x0d\罩衫x0a top++\x0d\x0a}\x0d\x0aif (p[top].n == 1) { /* 叶子结点 */\x0d\x0a move(p[top].x, 1, p[top].z)\x0d\x0a top--\x0d\x0a}\x0d\x0aif (top >= 0) { /* 向右走一步 */\x0d\x0a move(p[top].x, p[top].n, p[top].z)\x0d\x0a top--\x0d\x0a push(p, top, p[top+1].y, p[top+1].x, p[top+1].z, p[top+1].n)\x0d\x0a top++\x0d\x0a}\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint i\x0d\x0aprintf("递归:\n")\x0d\x0ahanoi(3, 'x', 'y', 'z')\x0d\x0aprintf("非递归:\n")\x0d\x0astruct hanoi p[MAXSTACK]\x0d\x0ac = 1\x0d\x0ap[0].n = 3\x0d\x0ap[0].x = 'x', p[0].y = 'y', p[0].z = 'z'\x0d\x0aunreverse_hanoi(p)\x0d\x0a\x0d\x0areturn 0\x0d\x0a}

将以下内容全部复制到新建的源文件中:(本人自己写的,因为你那课本上的代码,没解释,书写不规范,枯配搏很难理解清楚,所以我直接新写了一个完整的代码,附带详细说明)

#include <stdio.h>

//汉诺塔x层塔从A塔整体搬到C塔,中间临时B塔。

//x层塔是从大到小往上叠放。每次移动只能移动一层塔。并且在移动过程中必须保证小层在上边

//借助B塔可以将x层塔全部从A搬到C上,并且符合要求(在移动过程中大的那块在下边,小的那块在上边卖迟)

int main()

{

void tower(int x,char a,char b,char c) //声明函数

int x=5,a='A',b='B',c='C' //x表示有5层塔,具体要多少层自己修改这个值。abc分别表示ABC塔。

tower(x,a,b,c) //x层塔从a移动到c的全过程,主程序只有这条有效语句

return 0

}

//以下是tower函数的定义

//参数解析:x层塔放在a上,b是中间塔,c是目标塔。即x层塔要从a搬到c上。

//此函数实现x层塔从a整体转移到c上。以及这个过程是怎么搬的全部过程。

void tower(int x,char a,char b,char c)

{

if(x==1)printf("将%d从%c放到%c\n",x,a,c) //只有1层塔时,直接从a搬到c上。

else //不止1层塔,则先将x-1层塔从a按照规律搬到b上,再将最后一块从a搬到c上,最后再将b上的x-1层塔按没祥照规律搬到c上。

{

tower(x-1,a,c,b) //先将x-1层塔从a按照规律搬到b上,注意参数b放在最后,因为放在最后的参数是准备搬过去的目标塔。

printf("将%d从%c放到%c\n",x,a,c) //将最后一块从a搬到c上

tower(x-1,b,a,c) //最后再将b上的x-1层塔按照规律搬到c上,注意参数b放在开头,因为x-1层是要从b上搬过去的。

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12433580.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存