7.12 遞歸——雙色hanoi塔問題


今天為大家講一道非常有趣的問題,hanoi塔問題,相信很多同學都曾經玩過這個游戲,今天我們嘗試着靠編程來解決它

題目描述

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,編程計算最優移動方案。

輸入

輸入由多組測試數據組成。每組測試數據的第1 行是給定的正整數n。
 

輸出

對應每組輸入,輸出的每一行由一個正整數k和2 個字符c1 和c2 組成,表示將第k 個圓盤從塔座c1 移到塔座c2 上。

樣例輸入 Copy

3

樣例輸出 Copy

1 A B
2 A C
1 B C
3 A B
1 C A
2 C B
1 A B

提示

考察一個普通的漢諾塔問題,如果按照最少步驟移動(即沒有無意義的移來移去):

普通的漢諾塔(把盤子1~k由source移動到target)問題分三個階段
1.把盤子1~ k-1由source(k上面)移動到assistant
2.把盤子k由source移動到target
3.把盤子1~ k-1由assistant移動到target(k上面)
在這里我們把盤子1~ k-1的移動看做一個整體進行移動

那么假設存在一個違反雙色規則移動的盤子m-1,它放在了盤子m+1上,但是你讓盤子m怎么辦呢?在移動1~m+1這個層次並沒有盤子m在m+1所在柱子之外的兩個柱子間移動的步驟。
m-1放在m+3、m+5、m+7……之上也是不可能的,因為同樣地,就拿m+3來說,在移動1~m+3這個層次沒有盤子m+2在m+3所在柱子之外的兩個柱子間移動的步驟。

所以這種違規必然是一個多余的操作,違規地移動之后,必須要移下來才能正常繼續。
 
題解代碼:
#include<iostream>
#include<string>
using namespace std;
int n;
void hanoi(int k,char from,char assistant,char to){
 if(k==1){
  printf("%d %c %c\n",1,from,to);
  return ;
 }
 else{
  hanoi(k-1,from,to,assistant);
  printf("%d %c %c\n",k,from,to);
  hanoi(k-1,assistant,from,to);
 }
}
int main(){
 scanf("%d",&n);
 hanoi(n,'A','C','B');
 return 0;
}
 
題解思路:
  這道題的思路我們通過第一次遞歸hanoi(n,A,C,B)來講解,在將A底下最大的n的移到目的B柱之前,需要先將A柱上的1到n-1個環通過B移到C上,
我們可以利用第二次遞歸hanoi(n-1,A,B,C)來運算;在將A底下最大的n的移到目的B柱之后,我們便要將C上的1到n-1個環通過A柱移到B柱上,利用遞歸
hanoi(n-1,C,A,B)實現,每次遞歸只能移一個,搞清楚起始柱from,中間柱(協助作用)assistant和目的柱to的關系,即將最大的n由from移到to之前,需要將1到
n-1移到assistant上;移完后需將assistant的1到n-1再通過from移到to上來


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM