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/53384148
http://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;
}