难度:普及/提高-
题目描述
有 2n 个棋子排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为 n=5 的情况:
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如 n=5 时,成为:
任务:编程打印出移动过程。
输入格式
一个整数 n。
输出格式
若干行,表示初始状态和每次移动的状态,用 o 表示白子,* 表示黑子,- 表示空行。
输入输出样例
输入 #1
7
输出 #1
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*
说明/提示
4≤n≤100
思路
每两行分一组的时候,可以很明显地看到规律.
- 中间的 "o*" 与 "--" 交换
- 最左边的 "**" 与 "--" 交换
完整代码
#include<bits/stdc++.h>
using namespace std;
int n;
char ch[205]; //存储棋子的状态
void swap(char &a, char &b) //交换函数
{
char t = a;
a = b;
b = t;
}
void output(){ //输出
for (int i = 0; i < 2 * n + 2; i++)
putchar(ch[i]);
putchar('\n');
}
void movechess(int start, int end){ //移动棋子
swap(ch[start], ch[end]);
swap(ch[start + 1], ch[end + 1]);
output();
}
string out[4] = {"ooo*o**--*", "o--*o**oo*", "o*o*o*--o*", "--o*o*o*o*"};
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
ch[i] = 'o';
for (int i = n; i < 2 * n; i++)
ch[i] = '*';
ch[2 * n] = '-';
ch[2 * n + 1] = '-'; //打印初始状态
output();
int len = n; //需要移动的黑/白棋子
while (true){
movechess(len - 1, 2 * len); //中间的 "o*" 与 "--" 交换
len--;
if (len == 3) //不符合上述规律,开始输出打表内容
break;
movechess(len, 2 * len); //最左边的 "**" 与 "--" 交换
}
string ss;
for (int i = 0; i < n - 4; i++)
ss += "o*";
for (int i = 0; i < 4; i++)
cout << out[i] << ss << endl;
}