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;
}