5-17 汉诺塔的非递归实现 (25分)

5-17 汉诺塔的非递归实现   (25分)

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数。

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

输入样例:

3

输出样例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c

这道题确实比较难,参考两份博客http://blog.csdn.net/yhf_naive/article/details/53384148http://blog.csdn.net/computerme/article/details/18080511

然后根据这两份博客,我才勉强做出来。其实用栈来实现递归,主要也还是模拟了规律的本来实现。这个题目的循环部分,我觉得还是比较经典的,首先,移动一个盘子到中间的一个,然后在1,3两个之间重复操作,将小的移过去,当两种方法都行不通是,也就是说到达了极限值,这个时候,我们就要停止循环,。

以下是代码:

#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;

char s[4]={‘q‘,‘a‘,‘b‘,‘c‘};
stack<int> a[4];

bool my_move(int pre,int next)
{
if(a[pre].empty())
return false;
if(!a[next].empty())
{
if(a[pre].top()>a[next].top())
return false;
}
a[next].push(a[pre].top());
a[pre].pop();
printf("%c -> %c\n",s[pre],s[next]);
return true;
}

int main()
{
int n;
scanf("%d",&n);
for(int i=n-1;i>=0;i--)
a[1].push(i);
if(n%2==1)
{
s[2]=‘c‘;
s[3]=‘b‘;
}
int coun=0;
while(++coun)
{
my_move((coun-1)%3+1,coun%3+1);
if(!my_move((coun-1)%3+1,(coun+1)%3+1))
if(!my_move((coun+1)%3+1,(coun-1)%3+1))
break;
}
return 0;
}

时间: 2024-10-27 16:34:10

5-17 汉诺塔的非递归实现 (25分)的相关文章

7-17 汉诺塔的非递归实现 (25分)

一开始看见通过了0.4+,以为是送分题,结果我错了. 花了好长时间看博客没搞懂怎么非递归实现(菜……). 后面看了 https://blog.csdn.net/computerme/article/details/18080511的算法和https://zhuanlan.zhihu.com/p/36085324的非递归实现方法受到启发才把代码给敲出来. 下面简单说一下我理解到的方法吧! 第一步是判断输入的n是奇数还是偶数,若为奇数,则按顺时针以ACB的顺序摆成品字型,若为偶数,则按顺时针以ABC

7-17 汉诺塔的非递归实现

7-17 汉诺塔的非递归实现(25 分) 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标柱(标记为"c"),并保证每个移动符合汉诺塔问题的要求. 输入格式: 输入为一个正整数N,即起始柱上的盘数. 输出格式: 每个操作(移动)占一行,按柱1 -> 柱2的格式输出. 输入样例: 3 输出样例: a -> c a -> b c ->

汉诺塔的非递归实现(栈)

汉诺塔的非递归实现(栈) 美国学者找的规律:若是偶数,将a.b.c顺时针排列,否则a.c.b排列,然后反复做: (1)最小盘顺时针移动一个 (2)那两个柱子将最小的移动了,空的话直接移 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标柱(标记为"c"),并保证每个移动符合汉诺塔问题的要求. 输入格式: 输入为一个正整数N,即起始柱上的盘数. 输出格式:

汉诺塔问题的递归解法

汉诺塔问题的递归解法: 实现程序: #include<iostream> using namespace std; void move(int n, char i, char j) { cout << "把" << n << "号从" << i << "移动到" << j << endl; } void hanoi(int n, char x, cha

汉诺塔问题(递归与非递归)

汉诺塔比较经典的实现是利用递归,但也可以利用堆栈. 题意理解:有A,B,C三个柱子,将A柱子上的N个盘子(从大到小排列)移到C柱子上,每次只允许移动一个盘子,并且保证每个柱子上的盘子的排列都是从大到小. 1.递归实现 假设只有一个盘子,那么只需实现 A->C 这个动作: 如果有两个盘子,那么需要 (1)A->B; (2)A->C; (3)B->C; 如果有三个盘子,可以将前两个盘子看作一个盘子,对两个盘子重复以上三个步骤,于是得到N个盘子的递归算法,递归结束的条件是N=1: 1 v

汉诺塔问题非递归算法集锦

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 汉诺塔问题介绍: 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片,一次只移动一片,不管在哪根针上,小片必在大片上面.当所有的金片都从梵天穿好的那根针上移到另外一概针上时,世界就将在一声霹

汉诺塔问题的递归实现

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 1.汉诺塔(基本) 汉诺塔问题是典型的分治算法问题,首先我们来讨论最基本的汉诺塔问题.假设有n个圆盘,三根柱子,a,b,c,需要把n个盘子(从上往下从小到大摞着)从a柱移动到c柱,在小圆盘上不能放大圆盘,在三根柱

汉诺塔的简单递归思想

最近在校招打酱油,闲得没事想起了大一学过的汉诺塔,不过那时只知道玩游戏,一次性3~7个玩过了,还是有成就感的呵呵.游戏链接:http://www.7k7k.com/swf/335.htm. 看了网上很多递归方法,像 1 #include<stdio.h> 2 3 void move(int n,char a,char b,char c) 4 { 5 if(n==1) 6 printf("\t%c->%c\n",a,c); 7 else 8 { 9 move(n-1,a

汉诺塔问题(递归、栈)

修改一下汉诺塔的游戏规则,现在不能直接从左边走到右边,也不能直接右边走到左边. 方法一:递归实现 现在分析一下,比如左边有1~n,那么移动最后一个的情况,就是: 1.1-n-1从左边移动到右边 2.n从左边移动到中间 3.1-n-1从右边移动到左边 4.n从中间移动到右边 5.1-n-1从左边移动到右边 那么,假如我有这样一个f(range,from,to)那么我需要求解的就是f(n,lrft,right),原子情况就是从只有一个数的时候,直接左边中间右边即可. 1 public static