標籤:alt return 結果 int 技術 技術分享 分享 else 分治
分治3--黑白棋子的移動
一、心得
二、題目和分析
黑白棋子的移動(
chessman
)
【問題描述】 有2n個棋子(n≥4)排成一行,開始位置為白子全部在左邊,黑子全部在右邊,如為n=5的情形: ○○○○○●●●●● 移動棋子的規則是:每次必須同時移動相鄰的兩個棋子,顏色不限,可以左移也可以右移到空位上去,但不能調換兩個棋子的左右位置。每次移動必須跳過若干個棋子(不能平移),要求最後能移成黑白相間的一行棋子。如n=5時,成為: ○●○●○●○●○●任務:編程列印出移動過程。
【輸入範例】chessman.in 7
【輸出範例】chessman.outstep 0:ooooooo*******--step 1:oooooo--******o*step 2:oooooo******--o*step 3:ooooo--*****o*o*step 4:ooooo*****--o*o*step 5:oooo--****o*o*o*step 6:oooo****--o*o*o*step 7:ooo--***o*o*o*o*step 8:ooo*o**--*o*o*o*step 9:o--*o**oo*o*o*o*step10:o*o*o*--o*o*o*o*step11:--o*o*o*o*o*o*o*
【演算法分析】 我們先從n=4開始試試看,初始時: ○○○○●●●●第1步:○○○——●●●○● {—表示空位}第2步:○○○●○●●——●第3步:○——●○●●○○●第4步:○●○●○●——○●第5步:——○●○●○●○● 如果n=5呢?我們繼續嘗試,希望看出一些規律,初始時: ○○○○○●●●●●第1步:○○○○——●●●●○●第2步:○○○○●●●●——○● 這樣,n=5的問題又分解成了n=4的情況,下面只要再做一下n=4的5個步驟就行了。同理,n=6的情況又可以分解成n=5的情況,……,所以,對於一個規模為n的問題,我們很容易地就把他分治成了規模為n-1的相同類型子問題。 剛開始一點思路都沒有覺得問題特別複雜,其實根據我做的這一丟丟題看來,步驟或者說是流程說明性強的題目,都有一定的規律,可用遞迴遞推去做。這樣的題一定有一定的規律,如當n=5時,再稍加變動就恢複n=4時的情況,這就是有規律可循了,問題就變得簡單;再好比前面漢諾塔的題目,題目會仔細說明怎樣去移動,那就有規律可循了,不多解釋了,和這個題情況一樣,又會恢複到n-1的狀態;(快誇我!QWQ)初始化--輸出--移動n個棋子(函數)--怎樣移動(函數)--移動後輸出(輸出函數)
三、代碼和結果
1 #include <iostream> 2 using namespace std; 3 4 int n; 5 int step=0; 6 char ans[101]; 7 int sp; 8 9 void print(){10 cout<<"step"<<step<<":";11 for(int i=1;i<=2*n+2;i++) cout<<ans[i];12 cout<<endl;13 step++;14 }15 16 void init(int n){17 for(int i=1;i<=n;i++) ans[i]=‘o‘;18 for(int i=n+1;i<=2*n;i++) ans[i]=‘*‘;19 for(int i=2*n+1;i<=2*n+2;i++) ans[i]=‘-‘;20 print();21 sp=2*n+1;22 }23 24 void move(int k){25 for(int i=0;i<=1;i++){26 ans[sp+i]=ans[k+i];27 ans[k+i]=‘-‘;// 28 } 29 sp=k;30 print();// 31 }32 33 void mv(int n){34 if(n==4){35 move(4),move(8),move(2),move(7),move(1);36 }37 else{38 move(n),move(2*n-1),mv(n-1);39 }40 }41 42 int main(){43 cin>>n;44 init(n);45 mv(n);46 return 0;47 }
分治3--黑白棋子的移動