分治3--黑白棋子的移动

分治3--黑白棋子的移动

一、心得

 

二、题目和分析

 

黑白棋子的移动( chessman
【问题描述】
    有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:
    ○○○○○●●●●●
    移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:
     ○●○●○●○●○●
任务:编程打印出移动过程。
【输入样例】chessman.in
    7
【输出样例】chessman.out
step 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 } 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值