遞迴 雙色Hanoi塔問題

2021-10-17 03:16:13 字數 1811 閱讀 1018

​ 設a、b、c是3 個塔座。開始時,在塔座a 上有一疊共n 個圓盤,這些圓盤自下而上,由大到小地疊在一起。各圓盤從小到大編號為1,2,……,n,奇數號圓盤著藍色,偶數號圓盤著紅色。現要求將塔座a 上的這一疊圓盤移到塔座b 上,並仍按同樣順序疊置。在移動圓盤時應遵守以下移動規則:

​ 規則(1):每次只能移動1 個圓盤;

​ 規則(2):任何時刻都不允許將較大的圓盤壓在較小的圓盤之上;

​ 規則(3):任何時刻都不允許將同色圓盤疊在一起;

​ 規則(4):在滿足移動規則(1)-(3)的前提下,可將圓盤移至a,b,c 中任一塔座上。

​ 試設計乙個演算法,用最少的移動次數將塔座a 上的n個圓盤移到塔座b 上,並仍按同樣順序疊置。

​ 對於給定的正整數n,程式設計計算最優移動方案。

包含多組測試資料,每組測試資料報含乙個正整數n。

每組測試資料報含多行。每一行描述一步一定方案。

每一行由乙個正整數k和2個字元c1和c2組成,表示將第k個圓盤從塔座c1移到塔座c2上。

各資料之間用乙個空格隔開。

3
1  a  b

2 a c

1 b c

3 a b

1 c a

2 c b

1 a b

​ 漢諾塔問題之前一直是我這個蒟蒻在學習遞迴路上的攔路虎,或者可以說遞迴是我學習演算法路上的攔路虎。。。之前我一直糾結在要一直遞迴到什麼時候這個問題上,後來發現其實並不用太關注這裡,在寫**的時候,直接把遞迴函式當作乙個已完成的步驟來看就行,也就是說在自己閱讀**讀到遞迴那一步的時候,腦子裡應該直接單步跳過而不是單步進入

​ 廢話也說得差不多了,來說一下這個題的解法。漢諾塔問題是乙個很經典的遞迴演算法問題,我們把當前有盤子的柱子稱為now,目標柱子稱為target,剩下的乙個柱子稱為temp,解題的核心在於三步:

​ 1.把除了底部的部分全部移動到temp;

​ 2.把底部盤子移動到target;

​ 3.把temp的部分全部移動到target;

​ 先貼**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long int

#define scf scanf

#define prtf printf

#define mms(a) memset(a, 0, sizeof(a))

using

namespace std;

void

hanoi

(int stp,

char now,

char target,

char temp)

}int

main()

​ 需要說明的是,第21行雖然看起來像是把最上面的盤子從now移動到了target,但是實際上這個時候的now和target所對應的值並不是一開始所定義的值,因為在第24行的遞迴過程中,target被賦值為temp,所以說第21行實際上是把盤子從now移動到了temp。

從全域性的角度來看,now就是整個操作開始時盤子所在的柱子,而target就是最後需要到達的柱子,temp就是中間用來倒動的柱子,但是如果細化到具體的每一步的操作,那麼now,target,temp就應該是具體步驟所對應的柱子。

雙色Hanoi塔問題

設a,b,c是3個塔座。開始時,在塔座a上有一疊共n個圓盤,這些圓盤自下而上,由大到小地疊在一起。各圓盤從小到大編號為1,2,n,奇數號圓盤著藍色,偶數號圓盤著紅色。現要求將塔座a上的這一疊圓盤移到塔座b上,並仍按同樣順序疊置。在移動圓盤時應遵守以下移動規則 規則 1 每次只能移動1個圓盤 規則 2...

雙色Hanoi塔問題

雙色hanoi塔問題 問題描述 設a b c是3 個塔座。開始時,在塔座a 上有一疊共n 個圓盤,這些圓盤自下而上,由大到小地疊在一起。各圓盤從小到大編號為1,2,n,奇數號圓盤著藍色,偶數號圓盤著紅色,如圖所示。現要求將塔座a 上的這一疊圓盤移到塔座b 上,並仍按同樣順序疊置。在移動圓盤時應遵守以...

雙色Hanoi塔問題

題目描述 設a b c是3 個塔座。開始時,在塔座a 上有一疊共n 個圓盤,這些圓盤自下而上,由大到小地疊在一起。各圓盤從小到大編號為1,2,n,奇數號圓盤著藍色,偶數號圓盤著紅色,如圖所示。現要求將塔座a 上的這一疊圓盤移到塔座b 上,並仍按同樣順序疊置。在移動圓盤時應遵守以下移動規則 規則 1 ...