蓝桥杯-公平抽签

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;
}
posted @ 2024-04-09 22:38  DawnTraveler  阅读(27)  评论(0编辑  收藏  举报