按样例规律递归把规模 n 的局面缩成 n-1,直到 n=4 后输出固定收尾序列。
OJ: luogu
题目 ID: P1259
难度:普及-
标签:递归构造字符串python
日期: 2026-07-15 22:15
题意
有 n 个白子和 n 个黑子,末尾有两个空位。每次移动相邻两个棋子到空位,要求输出从初始状态到黑白相间状态的移动过程。
思路
这题不是搜索最短路,而是按固定规律构造输出。
把规模为 depth 的局面看成:
text
oooo...****...-- + 已经整理好的 o*o*...每一层先输出两步,把规模 depth 的问题缩成 depth-1 的问题:
text
oooo****--tail
ooo--***o*tail当规模缩到 4 时,剩下的收尾过程固定,直接输出 6 行。
Python 知识
- 字符串可以直接用
char * count重复。 - 把所有状态放入
states,最后用"\n".join(states)一次输出。 - 递归函数只负责追加状态,不需要真的模拟棋子数组。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md/home/rainboy/mycode/hugo-blog/content/program_language/python/cpp_to_python_pitfalls.md
代码
python
def repeated(char, count):
return char * count
def alternating(count):
return "o*" * count
def build_states(depth):
if depth == 4:
tail = alternating(n - 4)
states.append("oooo****--" + tail)
states.append("ooo--***o*" + tail)
states.append("ooo*o**--*" + tail)
states.append("o--*o**oo*" + tail)
states.append("o*o*o*--o*" + tail)
states.append("--o*o*o*o*" + tail)
return
tail_count = n - depth
states.append(repeated("o", depth) + repeated("*", depth) + "--" + alternating(tail_count))
states.append(repeated("o", depth - 1) + "--" + repeated("*", depth - 1) + alternating(tail_count + 1))
build_states(depth - 1)
n = int(input())
states = []
build_states(n)
print("\n".join(states))cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int n, cnt;
string states[100];
void dfs(int depth) {
if (depth == 4) {
string tail = "";
for (int i = 0; i < n - 4; i++) tail += "o*";
states[cnt++] = "oooo****--" + tail;
states[cnt++] = "ooo--***o*" + tail;
states[cnt++] = "ooo*o**--*" + tail;
states[cnt++] = "o--*o**oo*" + tail;
states[cnt++] = "o*o*o*--o*" + tail;
states[cnt++] = "--o*o*o*o*" + tail;
return;
}
string s = string(depth, 'o') + string(depth, '*') + "--";
for (int i = 0; i < n - depth; i++) s += "o*";
states[cnt++] = s;
s = string(depth - 1, 'o') + "--" + string(depth - 1, '*');
for (int i = 0; i < n - depth + 1; i++) s += "o*";
states[cnt++] = s;
dfs(depth - 1);
}
int main() {
cin >> n;
dfs(n);
for (int i = 0; i < cnt; i++) cout << states[i] << endl;
return 0;
}复杂度
输出行数为
总结
构造输出题要先观察样例规律。这里的核心是每轮把大规模局面缩小一层,最后用固定的 n=4 收尾。

