汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法
非递归算法:
根据圆盘的数量确定柱子的排放顺序:
若n为偶数,按顺时针方向依次摆放 A B C;
若n为奇数,按顺时针方向依次摆放 A C B。
然后进行如下操作:
(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。
(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。
C++实现:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
struct Hanoi
{
int n;
struct Tower
{
char Name;
stack<int> Disks;
}Tow[];
void init(int num)
{
n=num;
for(int i=;i<;i++)
{
Tow[i].Name='A'+i;
while(!Tow[i].Disks.empty()) Tow[i].Disks.pop();
}
for(int i=n;i>=;i--) Tow[].Disks.push(i);
}
void solve()
{
LL cnt=,cnt_max=(<<n)-;
while(cnt<cnt_max)
{
cnt++; int flag1,flag2;
if(cnt%)//第奇数次的移动
{
for(int i=;i<;i++) if(!Tow[i].Disks.empty() && Tow[i].Disks.top()==) flag1=i;
if(n%)//n为奇数
flag2=((flag1-)+)%;
else
flag2=(flag1+)%;
}
else//第偶数次的移动
{
flag1=flag2=-;
for(int i=;i<;i++)
{
if(!Tow[i].Disks.empty() && Tow[i].Disks.top()==) continue; if(flag1==-) flag1=i;
else if(flag2==-) flag2=i;
} if(!Tow[flag1].Disks.empty() && !Tow[flag2].Disks.empty())
{
if(Tow[flag1].Disks.top()>Tow[flag2].Disks.top()) swap(flag1,flag2);
}
else
{
if(Tow[flag1].Disks.empty()) swap(flag1,flag2);
}
} cout<<cnt<<": "<<"Move disk "<<Tow[flag1].Disks.top()<<" from "<<Tow[flag1].Name<<" to "<<Tow[flag2].Name<<endl;
Tow[flag2].Disks.push(Tow[flag1].Disks.top());
Tow[flag1].Disks.pop();
}
}
}hanoi;
int main()
{
int n;
cout<<"输入圆盘个数:"; cin>>n;
hanoi.init(n);
hanoi.solve();
}
递归算法:
设Hanoi(n,a,c,b)表示n个圆盘在a柱上,通过服从汉诺塔规则的若干步骤移动,在b柱的辅助下,全部按原顺序移动到了c柱上;
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
LL cnt;
void Hanoi(int n,char a,char c,char b)
{
if(n==)
{
cout<<++cnt<<": "<<"Move disk "<<n<<" from "<<a<<" to "<<c<<endl;
return;
} Hanoi(n-,a,b,c);
cout<<++cnt<<": "<<"Move disk "<<n<<" from "<<a<<" to "<<c<<endl;
Hanoi(n-,b,c,a);
return;
}
int main()
{
int n;
cout<<"输入圆盘个数:";
cin>>n;
cnt=;
Hanoi(n,'A','C','B');
}
汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法的更多相关文章
- 算法:汉诺塔问题(Tower of Brahma puzzle)
一.算法背景 最早发明这个问题的人是法国数学家爱德华·卢卡斯.传说越南河内某间寺院有三根银棒(A, B, C),上串 64 个金盘. 寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子:预言说当这 ...
- JavaScript算法实现之汉诺塔(Hanoi)
目前前端新手,看到的不喜勿喷,还望大神指教. 随着Node.js,Angular.js,JQuery的流行,点燃了我学习JavaScript的热情!以后打算每天早上跟晚上抽2小时左右时间将经典的算法都 ...
- C++例题2:汉诺塔问题
#include<iostream>#include<stdlib.h>using namespace std;void Hanoi(int n,char A,char B,c ...
- 汉诺塔 Hanoi Tower
电影<猩球崛起>刚开始的时候,年轻的Caesar在玩一种很有意思的游戏,就是汉诺塔...... 汉诺塔源自一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度 ...
- 用递归方法解决汉诺塔问题(Recursion Hanoi Tower Python)
汉诺塔问题源于印度的一个古老传说:梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.梵天命令婆罗门把圆盘按大小顺序重新摆放在另一根柱子上,并且规定小圆盘上不能放 ...
- 汉诺塔问题(Hanoi Tower)递归算法解析(Python实现)
汉诺塔问题 1.问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根 ...
- [CareerCup] 3.4 Towers of Hanoi 汉诺塔
3.4 In the classic problem of the Towers of Hanoi, you have 3 towers and N disks of different sizes ...
- 《hanoi(汉诺塔)问题》求解
//Hanoi(汉诺)塔问题.这是一个古典的数学问题,用递归方法求解.问题如下: /* 古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上. 有一个老和 ...
- 汉诺塔-Hanoi
1. 问题来源: 汉诺塔(河内塔)问题是印度的一个古老的传说. 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵 ...
随机推荐
- Layui:设置select下拉框自动选中某项
1.问题:layUI,在做编辑功能有下拉框数据时,需要初始化选中某个值,layUI官网没有相关api,可能我比较笨没找到 2.解决思路:出发点击事件 3.分析dom树结构,出发dl点击事件 方法: v ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 服务分组
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 服务分组 当一个接口有多种实现时,可以用group区分. <dubbo:se ...
- Spring boot配置log4j输出日志
1. pom.xml文件中配置parent,版本选定[1.2.5.RELEASE] 关于为什么要选这个版本:我尝试使用[1.4.1.RELEASE],但该版本库里没有[spring-boot-star ...
- 绕过D盾的一句话
一个很简单的一个技巧,作个笔记,可以绕过D盾检测. 新建test1.php <?php eval($_POST[g]); ?> 新建test2.php <?php $a=" ...
- 通过RF数据库查询中文字段结果正常显示的转换方法
方法1:统一显示为中文 1.通过RF数据库查询中文字段结果格式:'\xba\xcb\xbc\xf5\xcd\xa8\xb9\xfd' 2.通过Decode Bytes To String进行gbk解码 ...
- SpringBoot(二)-- 支持JSP
SpringBoot虽然支持JSP,但是官方不推荐使用.看网上说,毕竟JSP是淘汰的技术了,泪奔,刚接触 就淘汰.. SpringBoot集成JSP的方法: 1.配置application.prope ...
- 【译】Kafka学习之路
一直在思考写一些什么东西作为2017年开篇博客.突然看到一篇<Kafka学习之路>的博文,觉得十分应景,于是决定搬来这“他山之石”.虽然对于Kafka博客我一向坚持原创,不过这篇来自Con ...
- 老树开新花:DLL劫持漏洞新玩法
本文原创作者:丝绸之路 <img src="http://image.3001.net/images/20150921/14428044502635.jpg!small" t ...
- 使用JDBC插入数据到ORACLE,使用标识列自增列
不同于SQL Server的是,Oracle中插入数据的时候,没有自增列或者是标识列,但是,我们又不想显式的进行主键的插入,这里,必须在Oracle数据库中指定一个标识列,或者说是一个序列.具体方法如 ...
- Church 整数前驱的推导
Church 整数前驱的推导比其后继复杂得多,wiki中一个前驱的定义据王垠的博客里说,是他一个数学系的同学花一星期时间推导出来的, 其定义确实比其它介绍lambda的文章中用pair来实现(据说是图 ...