【分治】黑白棋子的移动

【题目描述】

有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:

○○○○○●●●●●

移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:

○●○●○●○●○●

任务:编程打印出移动过程。

【输入】

输入n。

【输出】

移动过程。

【输入样例】

7

【输出样例】

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*

【思路】:分治(NM分治的题肯定是分治了,怎么分啊?)其实这个题你仔细瞅瞅,就好发现它的棋子移动是有规律的,在结合分治的思想,把大问题分解成类似的小问题:
所以,问题分为两步:

  

1.把中间位置的一对黑白棋移到最右边。
2.把最左边的一对黑棋移到中间的空位上。

然后在看样例:

ooooooo*******--
oooooo--******o*
oooooo******--o*
ooooo--*****o*o*
ooooo*****--o*o*
oooo--****o*o*o*
oooo****--o*o*o*
ooo--***o*o*o*o*
ooo*o**--*o*o*o*
o--*o**oo*o*o*o*
o*o*o*--o*o*o*o*
--o*o*o*o*o*o*o*
发现就是这样的,嘿嘿嘿(好像思路顺序不对啊,
当n>4时,总是将中间的一对两个不同的棋子移到最右边的空位,然后再把最左边的黑棋子移到中间,如此往复,直到剩下四对黑白棋没有移动。


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
using namespace std;
const int maxn=999999999;
const int minn=-999999999;
int n;
int  step,cgp;
char a[520];
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
void print() {
    printf("step%2d:",step);
    for(int i=0; i<2*n+2; i++)
        printf("%c",a[i]);
    printf("\n");
    step++;
}
void fz(int k) { 
    int j;
    for(j=0; j<2; j++) {
        a[cgp+j]=a[k+j-1];
        a[k+j-1]='-';
    }
    cgp=k-1;
    print();
}
void move(int  m) {
    int i,k;
    if(m==4) {
        fz(4);
        fz(8);
        fz(2);
        fz(7);
        fz(1);
    } else {
        fz(m);
        fz(m*2-1);
        move(m-1);
    }
}
int main() {
    n=read();
    for(int i=0; i<n; ++i) {
        a[i]='o';
    }
    for(int i=n; i<2*n; ++i) {
        a[i]='*';
    }
    for(int i=2*n; i<=2*n+1; ++i) {
        a[i]='-';
    }
    cgp=2*n;
    print();
    move(n);
    return 0;
}




猜你喜欢

转载自www.cnblogs.com/pyyyyyy/p/10759290.html
今日推荐