理解 Hanoi 汉诺塔非递归算法
汉诺塔介绍:
汉诺塔(港台:河内塔)是根据一个传说形成的数学问题:
传说越南河内某间寺院有三根银棒,上串 64 个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子;预言说当这些盘子移动完毕,世界就会灭亡。这个传说叫做梵天寺之塔问题(Tower of Brahma puzzle)。但不知道是卢卡斯自创的这个传说,还是他受他人启发。
若传说属实,僧侣们需要 \(2^{64}-1\)步才能完成这个任务;若他们每秒可完成一个盘子的移动,就需要5849 亿年才能完成。整个宇宙现在也不过 137 亿年。
这个传说有若干变体:寺院换成修道院、僧侣换成修士等等。寺院的地点众说纷纭,其中一说是位于越南的河内,所以被命名为“河内塔”。另外亦有“金盘是创世时所造”、“僧侣们每天移动一盘”之类的背景设定。
介绍完汉诺塔背景以后开始解决下非递归思路
汉诺塔的非递归算法描述如下:
首先容易证明,当盘子的个数为n时,
假设有 n 片,移动最少次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。
此后不难证明 n 片时移动的次数应等于2\(^n - 1\)。
一位美国学者发现一种出人意料的方法,只要轮流进行两步操作就可以了。
我们假设现在最小的圆盘在a柱子上,柱子为a,b,c
第一步:将最小圆盘移动到下一个柱子上,也就是b
第二步:对a柱子和c柱子进行顶上最小的元素进行判断,把小一点的那个圆盘移动到大一点的那个圆盘(有空则摞在空柱子上)。
反复进行前面两步操作,最后就能按规定完成汉诺塔的移动。
注意:这样得到的最后的答案不一定是摞在c上,如果N是偶数将摞在b上,所以如果N是偶数我们就令第二个柱子为c,第三个柱子为b,这样就一定最后是摞在c上的。
汉诺塔非递归算法实现
#include<iostream>
#include<stack>
using namespace std;
char s[3] = { 'a', 'b', 'c' };//代表3个柱子
stack<int> a[3];
bool move(int before, int after)
{
if (a[before].empty())
return false;
if (!a[after].empty()){
if (a[after].top() - a[before].top() < 0)
return 0;
}
a[after].push(a[before].top());
a[before].pop();
printf("%c -> %c\n", s[before], s[after]);
return true;
}
int main()
{
int N, count = 0;
cin >> N;
for (int i = 0; i < N; i++)
a[0].push(N - i);
if (N % 2 == 1)
{
s[1] = 'c';
s[2] = 'b';
}
while (++count){
move((count - 1) % 3, count % 3);
if (!move((count - 1) % 3, (count + 1) % 3))
if (!move((count + 1) % 3, (count - 1) % 3))
break;
}
return 0;
}
查找资料的时候发现N皇后问题与汉诺塔的非递归有类似又不同的思想,这几天赶快安排下学习N皇后(偷懒好久了2333)
理解 Hanoi 汉诺塔非递归算法的更多相关文章
- [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 ...
- Python汉诺塔问题递归算法与程序
汉诺塔问题: 问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 ...
- 使用函数的递归调用来解决Hanoi(汉诺)塔问题。
#include<stdio.h> void hanoi(int n, char x, char y, char z); void move(char x, char y); int ti ...
- Hanoi汉诺塔问题——递归与函数自调用算法
题目描述 Description 有N个圆盘,依半径大小(半径都不同),自下而上套在A柱上,每次只允许移动最上面一个盘子到另外的柱子上去(除A柱外,还有B柱和C柱,开始时这两个柱子上无盘子),但绝不允 ...
- C语言之算法初步(汉诺塔--递归算法)
个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考.记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果.现在想 ...
- python的递归算法学习(3):汉诺塔递归算法
汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之 ...
- 《hanoi(汉诺塔)问题》求解
//Hanoi(汉诺)塔问题.这是一个古典的数学问题,用递归方法求解.问题如下: /* 古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上. 有一个老和 ...
- 数据结构--汉诺塔--借助栈实现非递归---Java
/*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...
- 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法
非递归算法: 根据圆盘的数量确定柱子的排放顺序: 若n为偶数,按顺时针方向依次摆放 A B C: 若n为奇数,按顺时针方向依次摆放 A C B. 然后进行如下操作: (1)按顺时针方向把圆盘1从现在的 ...
随机推荐
- SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析
目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...
- JVM01——JVM内存区域的构成
从本文开始将为各位带来JVM方面的知识点,关注我的公众号「Java面典」了解更多Java相关知识点. JVM内存主要分为三部分线程私有(Thread Local).线程共享(Thread Shared ...
- 利用mnist数据集进行深度神经网络
初始神经网络 这里要解决的问题是,将手写数字的灰度图像(28 像素 x28 像素)划分到 10 个类别中(0~9).我们将使用 MINST 数据集,它是机器学习领域的一个经典数据集,其历史几乎和这个领 ...
- 如何快速高效率地学习Go语言
要想快速高效率地掌握Go语言,关键是要通过不断写代码去训练,熟能生巧.方法是没问题的,但具体的路径呢?就像开车,能不能给个导航?我希望这篇文章能起到一个导航的作用,这里提供的路径,应该对很多人都适合. ...
- java第一次上机练习作业
1.已知a,b均是整型变量,写出将a,b两个变量中的值互换的程序.(知识点:变量和 运算符综合应用) int a = 5, b = 10; int temp; temp = a; a = b; b = ...
- 读源码 - stagesepx
目录 背景 一.概述 stagesepx 二.源码中优雅的用法 优雅的赋值/返回 递归方法新建多级目录 更简洁的日志输出 格式化输出的另一种姿势 基于生成器读取多个文件 sorted进阶 入参类型限制 ...
- Requests发Post请求data里面嵌套字典
一.Post请求,data里面嵌套字典 Requests发Post请求,data里面嵌套字典的常见形式如下: info = { "appid": "123", ...
- Linux常用命令 - top命令详解(重点)
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html top ...
- JVM年轻代,老年代,永久代详解
前言 最近被问到了这个问题,解释的不是很清晰,有一些概念略微模糊,在此进行整理和记录,分享给大家.本篇文章主要讲解内存区域的年轻代,老年代和永久代,略微提及一些垃圾回收算法,下面是正文. 堆整体 堆主 ...
- WEB应用之httpd基础入门(三)
前文我们聊到了httpd的路径别名.访问日志定义.basic认证配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12561236.html:今天我们来聊一聊 ...