swustoj 143 漢諾塔問題

Description

(n階Hanoi塔問題)假設有三個分別命名爲A、B、C的塔座,在塔座A上插有n(n<20)個直徑大小各不相同、依小到大編號爲1,2,…,n的圓盤。現要求將A軸上的n個圓盤移至塔座C上並仍按同樣順序疊排,圓盤移動時必須遵循下列規則: 1)每次只能移動一個圓盤; 2)圓盤可以插在A、B、C中的任一塔座上; 3)任何時刻都不能將一個較大的圓盤壓在較小的圓盤之上。 請通過編程來打印出移動的步驟.

Input

只有一組輸入數據.輸入數據N(;表示在開始時A塔座上的盤子數),當輸入0時程序結束.

Output

輸出移動的步驟.如"A-->C","A-->B"等.每兩的步驟之間有三個空格隔開,每輸出5個步驟就換行.詳細的見Sample Output.

Sample Input

5

2

0

 

Sample Output

A--&gt;C A--&gt;B C--&gt;B A--&gt;C B--&gt;A

B--&gt;C A--&gt;C A--&gt;B C--&gt;B C--&gt;A

B--&gt;A C--&gt;B A--&gt;C A--&gt;B C--&gt;B

A--&gt;C B--&gt;A B--&gt;C A--&gt;C B--&gt;A

C--&gt;B C--&gt;A B--&gt;A B--&gt;C A--&gt;C

A--&gt;B C--&gt;B A--&gt;C B--&gt;A B--&gt;C

A--&gt;C

A--&gt;B A--&gt;C B--&gt;C 

 

Hint

注意:此題每一行最後有3個空格

 

首先說一下,題目上的輸出亂了,我直接複製的沒有改,&gt應該是>

 

漢諾塔問題是個很經典的遞歸問題,但也比較難理解。

 

解題的方法大致是:移動當前n階漢諾塔的最大一個盤子到目的柱子疊起來,將n階漢諾塔變成n-1級漢諾塔,然後重複挪n-1箇中最大的盤子到目的柱子,直到挪成一階漢諾塔

先寫一下核心的解法

void move(int n,char x,char y,char z)

{
if (n == 1)
{
printf("%c-->%c   ", x, z);
return;
}
move(n-1,x,z,y);
printf("%c-->%c   ",x, z);
move(n-1,y,x,z);
}

下面是ac代碼及詳解:

 

#include<stdio.h>
int vis;//這個參數和算法無關,只是爲了標記,滿足題目的五步一換行,否則題目會PE
int main()
{
	int n;
	void move(int n, char x, char y, char z);//******此函數的作用是將x柱子上的n個盤子移動到z柱子上,同時輸出要經歷的步驟

	while (~scanf("%d",&n) && n)
	{
		vis=1;
		move(n, 'A', 'B', 'C');//函數的直接目的,將A柱上的盤子移到C柱,同時輸出步驟
		if ((--vis % 5))printf("\n");//如果最後一位剛好是第五個
	}
	return 0;
}

void move(int n,char x,char y,char z)//x爲初始塔,y表示藉助塔,z表示目標塔。
{
//******此函數的作用是將x柱子上的n個盤子移動到z柱子上,同時輸出要經歷的步驟,x上面的盤子始終是由小到大
//x表示當前要移動的盤子所在的柱子,n表示當前有多少個盤子在x上,y表示藉助y柱子,z表示需要把x上的n個盤子移動到z柱子上。
	

	if (n == 1)//n=1時,x上只剩一個盤子的時候,直接移動到z
	{
		printf("%c-->%c   ", x, z);
		if (!(vis++ % 5))printf("\n");
		return;
	}
	//n>1時,x上還有n個盤子的時候,當前目的就是把上面的n-1個盤子全挪到y上,這樣就可以把當前最大的那個盤子挪到z上
	//怎麼挪呢?

	move(n-1,x,z,y);//首先請看上面注了六個*號的那句話。
	//不管這步的函數內部是怎麼運行的,總之,這個函數的運行後的效果是將x柱子上的n-1個盤子移動到y柱子上

	printf("%c-->%c   ",x, z);//移動x上的盤子到z上,ps:雖然沒有挪動這個操作,但挪動到目標位置後就不用管了,變成了n-1階漢諾塔,所以直接無視掉它
	if (!(vis++ % 5))printf("\n");//五個一換行
	//關鍵是要知道每步的作用是什麼,不用去想它是怎麼做到的
	//現在我們的目的就變成了將y上的n-1個盤子移動到z上
	move(n-1,y,x,z);//接下來我們只需要解決n-1階漢諾塔了,也就是這個函數的目的,將y上剩餘的n-1個盤子移動到z柱子上
}


成在堅持,貴在堅持,難在堅持!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章