設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 ...