zoukankan      html  css  js  c++  java
  • 【分治】黑白棋子的移动

    【题目描述】

    有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("
    ");
        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;
    }




  • 相关阅读:
    面试题
    iOS 两种方法实现左右滑动出现侧边菜单栏 slide view
    进程、线程、多线程相关总结
    iOS开发
    播放 视频
    delphi控件属性大全-详解-简介
    Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值
    FastReport 使用说明
    delphi的取整函数round、trunc、ceil和floor
    cxGrid 速度
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/10759290.html
Copyright © 2011-2022 走看看