通过按位决策的回溯搜索树,依次枚举未使用的数字生成字典序排列。
OJ: roj
题目 ID: 3008
难度:入门
标签:递归搜索回溯
创建: 2026-10-01 09:32
更新: 2026-10-06 11:13
题目描述
把
text
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1思路
把排列看成从左到右逐个位置填数字:dfs(pos) 从 1 到 n 依次尝试每个未使用的数字填进第 pos 个位置,标记后递归、返回后取消标记(回溯),pos 到达 n 时输出当前排列。由于每层从小到大枚举,输出天然满足字典序。
参考代码
Python 版:
python
#!/usr/bin/env python3
# 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-10-01 09:32
# update_at: 2026-10-01 09:32
import sys
from collections.abc import Iterator
def generate_permutations(n: int) -> Iterator[str]:
"""生成 1 到 n 的所有全排列,每项格式化为行末带空格的字符串。"""
chosen = [False] * (n + 1)
path = [0] * n
def dfs(pos: int) -> Iterator[str]:
if pos == n:
yield " ".join(map(str, path)) + " "
return
for num in range(1, n + 1):
if not chosen[num]:
chosen[num] = True
path[pos] = num
yield from dfs(pos + 1)
chosen[num] = False
yield from dfs(0)
def solve() -> None:
data = iter(sys.stdin.buffer.read().split())
token = next(data, None)
if token is None:
return
n = int(token)
lines = list(generate_permutations(n))
sys.stdout.write("\n".join(lines) + "\n")
if __name__ == "__main__":
solve()C++ 版(同一算法):
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-10-06 11:13
* update_at: 2026-10-06 11:13
*/
#include <cstdio>
typedef long long ll;
const int MAXN = 9 + 5;
ll n; // 题目给出的 n,排列长度
ll path[MAXN]; // path[pos] 表示第 pos 个位置填的数字
bool used[MAXN]; // used[i] 表示数字 i 是否已经被选用
// dfs(pos):这一层在为第 pos 个位置选择一个未使用的数字
void dfs(ll pos) {
if (pos == n) { // 前 n 个位置全部填满,输出当前排列
for (ll i = 0; i < n; i++) printf("%lld ", path[i]);
printf("\n");
return;
}
// 从小到大尝试每个数字,保证输出按字典序
for (ll i = 1; i <= n; i++) {
if (used[i]) continue;
used[i] = true;
path[pos] = i;
dfs(pos + 1);
used[i] = false; // 回溯恢复现场
}
}
int main() {
scanf("%lld", &n);
dfs(0);
return 0;
}