题目描述
有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) imes2+5$。
#include <iostream> #include <algorithm> #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; }