P1259 黑白棋子的移动 题解
题目描述
有 $2n$ 个棋子排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为 $n=5$ 的情况:
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如 $n=5$ 时,成为:
任务:编程打印出移动过程。
输入格式
一个整数 $n$。
输出格式
若干行,表示初始状态和每次移动的状态,用 $\verb!o!$ 表示白子,$\verb!*!$ 表示黑子,$\verb!-!$ 表示空行。
Speical Judge
样例 #1
样例输入 #1
17
样例输出 #1
1
2
3
4
5
6
7
8
9
10
11
12
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\leq n\leq 100$
题解
看着似乎没有头绪?我们不妨先按照样例所示的规律来用纸笔画一画
1 |
|
然后再考虑几种简单的
1 |
|
1 |
|
这个时候我们可以注意到如下几个细节:
-
最后5行的规律总是相同的:即
1
2
3
4
5ooo--***o*
ooo*o**--*
o--*o**oo*
o*o*o*--o*
--o*o*o*o*再在末尾跟上n-4个"o*"
-
前面部分的移动规律:考虑i从第n个开始,交换i和i+i+1的位置,交换i-1和i-1+i+1的位置,输出改变之后的字符串;然后再交换i和i+i-1的位置,交换i-1和i-1+i-1的位置,再输出
(这样的规律是如何发现的?可以多写出来诸如这样的部分
开始(n=7时) 第一次交换的下标 第二次交换的下标 i=7 15 13 i-1=6 14 12 i=6 13 11 i-1=5 12 10 i=5 11 9 i-1=4 10 8 差值 i+1 i-1 得到差值之后也就轻松了。
)
这样的移动操作总共需要进行n-4次,也就是i从n遍历到5即可
(为什么是n-4次?也可以从最后的角度考虑,我们要创造出n-4个"o*",而每进行一次这样的操作就是会多一个"o*"的结构
于是我们就可以进行代码实现了
1 |
|
还有一个需要注意的点
这样去初始化字符串
1 |
|
是不可以的。因为直接通过下标访问一个空字符串的字符是未定义行为(undefined behavior),这可能导致程序崩溃或没有任何输出。
正确做法:统一使用push_back()函数。
P1259 黑白棋子的移动 题解
http://example.com/2025/01/23/洛谷P1259 黑白棋子的移动 题解/