1. 程式人生 > >漢諾塔的非遞迴實現(25 分)

漢諾塔的非遞迴實現(25 分)

藉助堆疊以非遞迴(迴圈)方式求解漢諾塔的問題(n, a, b, c),即將N個盤子從起始柱(標記為“a”)通過藉助柱(標記為“b”)移動到目標柱(標記為“c”),並保證每個移動符合漢諾塔問題的要求。

輸入格式:

輸入為一個正整數N,即起始柱上的盤數。

輸出格式:

每個操作(移動)佔一行,按柱1 -> 柱2的格式輸出。

//說說思路,根據網上對漢諾塔的總結,用stack完全模擬過程,即可得出答案。

//來自百度的解釋。

其實演算法非常簡單,當盤子的個數為n時,移動的次數應等於2^n – 1(有興趣的可以自己證明試試看)。後來一位美國學者發現一種出人意料的簡單方法,只要輪流進行兩步操作就可以了。首先把三根柱子按順序排成品字型,把所有的圓盤按從大到小的順序放在柱子A上,根據圓盤的數量確定柱子的排放順序:若n為偶數,按順時針方向依次擺放 A B C;

若n為奇數,按順時針方向依次擺放 A C B。

⑴按順時針方向把圓盤1從現在的柱子移動到下一根柱子,即當n為偶數時,若圓盤1在柱子A,則把它移動到B;若圓盤1在柱子B,則把它移動到C;若圓盤1在柱子C,則把它移動到A。

⑵接著,把另外兩根柱子上可以移動的圓盤移動到新的柱子上。即把非空柱子上的圓盤移動到空柱子上,當兩根柱子都非空時,移動較小的圓盤。這一步沒有明確規定移動哪個圓盤,你可能以為會有多種可能性,其實不然,可實施的行動是唯一的。

⑶反覆進行⑴⑵操作,最後就能按規定完成漢諾塔的移動。

輸入樣例:

3

輸出樣例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c
//用程式碼模擬百度給的搬運思路//
#include<string>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
int main()
{
	stack < int > a,b,c;
	int i,j,n;
	cin>>n;
	char s[4]={'p','a','b','c'}; 
	a.push(99999); b.push(999999); c.push(999999);
	for(i=n;i>=1;i--)
	{
		a.push(i);
	 } 
	if(n%2==1)
	{
		s[2]='c';
		s[3]='b';
	}
	 for(i=1;;i++)
	 {
	 	if(i%3==1)
	 	{
	 		printf("%c -> %c\n",s[1],s[2]);
	 		b.push(a.top());
	 		a.pop();
	 			if(b.size()==n+1||c.size()==n+1)
		break;
	 		if(c.top()>a.top())
	 		{
	 			printf("%c -> %c\n",s[1],s[3]);
	 			c.push(a.top());
	 			a.pop();
			 }
			 else
			 {
			 	printf("%c -> %c\n",s[3],s[1]);
			 	a.push(c.top());
			 	c.pop();
			 }
		 }
		else if(i%3==2)
		{
			printf("%c -> %c\n",s[2],s[3]);
			c.push(b.top());
	 		b.pop();
	 			if(b.size()==n+1||c.size()==n+1)
		break;
	 		if(b.top()>a.top())
	 		{
	 			printf("%c -> %c\n",s[1],s[2]);
	 			b.push(a.top());
	 			a.pop();
			 }
			 else
			 {
			 	printf("%c -> %c\n",s[2],s[1]);
			 	a.push(b.top());
			 	b.pop();
			 }
		}
		else
		{
			printf("%c -> %c\n",s[3],s[1]);
			a.push(c.top());
	 		c.pop();
	 			if(b.size()==n+1||c.size()==n+1)
		break;
	 		if(c.top()>b.top())
	 		{
	 			printf("%c -> %c\n",s[2],s[3]);
	 			c.push(b.top());
	 			b.pop();
			 }
			 else
			 {
			 	printf("%c -> %c\n",s[3],s[2]);
			 	b.push(c.top());
			 	c.pop();
			 }
			i=0;
		}
//		if(b.size()==n+1||c.size()==n+1)
//		break;
		
		
	 }

 }