【题解】棋子移动

题目描述

        有2n(n≥4)个棋子排成一行,开始位置为白子全部在左边,黑子全部在右边。例如n=5时:00000+++++。移动棋子的规则是:每次必须同时移动相邻两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,称为:__0+0+0+0+0+。

 

输入格式

        一行,仅输入黑棋和白棋的数目n(4≤n≤1000)。

 

输出格式

        输出各行每一步的移动结果,最后一行输出总移动步数,其中用“0”(大写字母)表示白棋,用星号表示黑棋,用“__”(两个下划线)表示两个空位。

 

输入样例

5

 

输出样例

0000__****0*

0000****__0*

000__***0*0*

000*0**__*0*

0__*0**00*0*

0*0*0*__0*0*

__0*0*0*0*0*

step=7

 

题解

        当$n>4$时,移动$2$次可以转换成$n-1$的情况,转换到$n=4$时直接暴力输出移动路线,然后递归回去即可,据此容易想到总移动步数为$(n-4)\times2+5$。

#include 
#include 
#define MAXN 2002

using namespace std;

int n;
char a[MAXN];

inline void move(int now, int to)
{
    swap(a[now], a[to]);
    swap(a[now + 1], a[to + 1]);
    for(register int i = 1; i <= n * 2 + 2; i++) cout << a[i];
    cout << endl;
    return;
}

void func(int x)
{
    if(x == 4)
    {
        move(4, 9);
        move(8, 4);
        move(2, 8);
        move(7, 2);
        move(1, 7);
        return;
    }
    move(x, x * 2 + 1);
    move(x * 2 - 1, x), 
    func(x - 1);
    return;
}

int main()
{
    cin >> n;
    for(register int i = 1; i <= n; i++)
    {
        a[i] = 'O';
        a[i + n] = '*';
    }
    a[n * 2 + 1] = a[n * 2 + 2] = '_';
    func(n);
    cout << "step=" << 5 + (n - 4) * 2;
    return 0;
}
参考程序

 

转载于:https://www.cnblogs.com/kcn999/p/10702924.html

你可能感兴趣的:(【题解】棋子移动)