用 itertools.combinations 按字典序枚举 1 到 n 中选 r 个数,并用格式化字符串控制每个数宽度为 3。
OJ: luogu
题目 ID: P1157
难度:入门
标签:枚举组合python
日期: 2026-07-15 21:30
题意
从 1..n 中选出 r 个数,按字典序输出所有组合。每个数字输出时占 3 个字符宽度。
思路
组合要求:
- 每行内部数字递增;
- 所有行按字典序排列;
- 不关心选择顺序,只关心选出的集合。
itertools.combinations(range(1, n + 1), r) 正好满足这些条件。它会按照输入序列的顺序生成组合,所以输出顺序就是题目要求的字典序。
每个数占 3 个字符,可以写成:
python
f"{number:3d}"再把一行中的字段拼接起来输出。
Python 知识
combinations(range(1, n + 1), r)表示从1..n中选r个。f"{number:3d}"是格式化字符串,含义是整数右对齐,占3个字符宽度。"".join(...)把一行的多个格式化字段拼成一个字符串。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/brute_force_validation.md/home/rainboy/mycode/hugo-blog/content/program_language/python/itertools_recipes.md/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md
代码
python
from itertools import combinations
n, r = map(int, input().split())
for chosen in combinations(range(1, n + 1), r):
print("".join(f"{number:3d}" for number in chosen))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, r;
int choose[25];
void dfs(int dep, int start) {
if (dep == r) {
for (int i = 0; i < r; i++)
cout << setw(3) << choose[i];
cout << endl;
return;
}
for (int i = start; i <= n; i++) {
choose[dep] = i;
dfs(dep + 1, i + 1);
}
}
int main() {
cin >> n >> r;
dfs(0, 1);
return 0;
}复杂度
会输出 r 个数。时间复杂度为
总结
这题的重点不是手写递归,而是学会把“按字典序输出组合”直接交给 itertools.combinations。