蓝桥杯-公平抽签
0.题目
题目描述
小A的学校,蓝桥杯的参赛名额非常有限,只有 m 个名额,但是共有 n 个人报名。
作为老师非常苦恼,他不知道该让谁去,他在寻求一个绝对公平的方式。
于是他准备让大家抽签决定,即 m 个签是去,剩下的是不去。
小 A 非常想弄明白最后的抽签结果会有多少种不同到情况,请你设计一个程序帮帮小 A!
输入描述
输入第一行包含两个字符 n,m,其含义如题所述。
接下来第二行到第 n+1 行每行包含一个字符串 S ,表示个人名。
1≤m≤n≤15。
输出描述
输出共若干行,每行包含 m 个字符串,表示该结果被选中到人名(需按字符串的输入顺序大小对结果进行排序)。
输入输出样例
示例
输入
3 2
xiaowang
xiaoA
xiaoli
输出
xiaowang xiaoA
xiaowang xiaoli
xiaoA xiaoli
1.题解
1.1 组合型枚举-回溯分析法
思路
套用组合型枚举(\(C_n^m\))的模板代码即可
代码
#include<bits/stdc++.h>
using namespace std;
int n, m;
string vec[16];
vector<string> chosen;
// x代表遍历的当前位x
void DFS(int x){
// 已选数目大于 m 或者 剩余数目和已选数目加起来不够m, 就不用继续讨论了
if(chosen.size() > m || (chosen.size() + n - x + 1)< m) return;
// 一共[1,n], x==n+1 已经遍历完了,如果通过了上面的条件,说明这里确实是选中了m个的
if(x == n + 1){
for(string str : chosen){
cout << str << " ";
}
cout << endl;
return;
}
// 选中当前数
chosen.push_back(vec[x]);
DFS(x + 1);
// 不选中当前数
chosen.pop_back();
DFS(x + 1);
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> vec[i];
}
DFS(1);
return 0;
}