说到暴力,我们大家最先想到一定是枚举,但是枚举真的是一门技术,怎么样把所有情况一个不落下的枚举出来是比较难的,后面将给出3种枚举
目录
-
简单型枚举
-
普通枚举思想为:将问题的所有可能成为答案的解一一列举,然后根据问题所给出的条件判断此解是否合适,如果合适就保留,反之则舍弃。
- 确定枚举解的范围,以及判断条件
- 选取合适枚举方法,进行逐一枚举,此时应注意能否覆盖所有的可能的解
- 在枚举时使用判断条件检验,留下所有符合要求的解。
题目描述
请你设计一个程序对该问题进行解答。
众所周知在扑克牌中,有一个老掉牙的游戏叫做 2424 点,选取 44 张牌进行加减乘除,看是否能得出 2424 这个答案。
现在小蓝同学发明了一个新游戏,他从扑克牌中依次抽出6张牌,注意不是一次抽出,进行计算,看是否能够组成 4242 点,满足输出 YES
,反之输出 NO
。
最先抽出来的牌作为第一个操作数,抽出牌做第二个操作数,运算结果再当作第一个操作数,继续进行操作。
注:除不尽的情况保留整数,而且扑克牌的四张 1010 都丢了,不会出现 1010。
请设计一个程序对该问题进行解答。
输入描述
输出仅一行包含 66 个字符。
保证字符 ∈∈ 3 4 5 6 7 8 9 10 J Q K A 2
。
输出描述
若给出到字符能够组成 4242 点 , 满足输出 YES
,反之输出 NO
。
输入输出样例
示例
输入
K A Q 6 2 3
输出
YES
代码:
#include <iostream>
#include <vector>
using namespace std;
int a[10];
vector <int> ans[10];
int main()
{
for(int i=0; i<6; i++)
{
char c;
cin>>c;
if(c=='A')
a[i]=1;
else if(c=='J')
a[i]=11;
else if(c=='Q')
a[i]=12;
else if(c=='K')
a[i]=13;
else
a[i]=(c-'0');
//cout<<a[i]<<endl;
}
ans[0].push_back(a[0]);
for(int i=1; i<=5; i++)
{
for(int j=0; j<ans[i-1].size(); j++)
{
ans[i].push_back(ans[i-1][j]+a[i]);
ans[i].push_back(ans[i-1][j]-a[i]);
ans[i].push_back(ans[i-1][j]*a[i]);
ans[i].push_back(ans[i-1][j]/a[i]);
}
}
//cout<<ans[5].size()<<endl;
int flag=0;
for(int i=0; i<ans[5].size(); i++)
{
if(ans[5][i]==42)
{
flag=1;
break;
}
}
if(flag==1)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
-
组合型枚举
-
解析:
-
排列组合相信大家都学习过,组合型枚举就是让你在 n 个中,随机选出 m 个,问你有多少种方案,而且每一种方案选择了哪 m 个,这就是组合型枚举。
-
题目描述
小AA的学校,蓝桥杯的参赛名额非常有限,只有 mm 个名额,但是共有 nn 个人报名。
作为老师非常苦恼,他不知道该让谁去,他在寻求一个绝对公平的方式。
于是他准备让大家抽签决定,即 mm 个签是去,剩下的是不去。
小AA非常想弄明白最后的抽签结果会有多少种不同到情况,请你设计一个程序帮帮小AA!
输入描述
输入第一行包含两个字符 n,mn,m,其含义如题所述。
接下来第二行到第 n+1n+1 行每行包含一个字符串 SS ,表示个人名。
1≤m≤n≤151≤m≤n≤15。
输出描述
输出共若干行,每行包含 mm 个字符串,表示该结果被选中到人名。
输入输出样例
示例
输入
3 2 xiaowang xiaoA xiaoli
输出
xiaowang xiaoA xiaowang xiaoli xiaoA xiaoli
模版:
-
int n;//共计N个数 int m;//选m个数 vector<int> chosen; void calc(int x) { if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝 return; if (x == n + 1) { //选够了m个数输出 for (int i = 0; i < chosen.size(); i++) printf("%d ", chosen[i]); //也可以不输出,存放起来也是可以的,主要是看题目。 puts(""); return; } calc(x + 1); chosen.push_back(x); calc(x + 1); chosen.pop_back();//消除痕迹 } int main() { cin>>n>>m; calc(1); }
-
代码:
-
#include <iostream> #include <vector> using namespace std; int n; //共计N个数 int m; //选m个数 vector<string> name; vector<string> ans; vector<int> chosen; void calc(int x) { if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝 return; if (x == n + 1) { //选够了m个数输出 string ansTem = ""; for (int i = 0; i < chosen.size(); i++) ansTem += name[chosen[i] - 1] + " "; ans.push_back(ansTem); return; } calc(x + 1); chosen.push_back(x); calc(x + 1); chosen.pop_back(); //消除痕迹 } int main() { cin >> n >> m; for (int i = 0; i < n; i++) { string s; cin >> s; name.push_back(s); } calc(1); for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i] << endl; }
-
排列型枚举
- 解析:
- 而排列型枚举相对组合型枚举就简单了一点,就是 n 个的全排列,即从 n 个中选取 n 个但是关心内部的顺序。
-
题目描述
小 AA 的学校,老师好不容易解决了蓝桥杯的报名问题,现在老师又犯愁了。
现在有 NN 位同学参加比赛,但是老师想给他们排座位,但是排列方式太多了。
老师非常想弄明白最后的排座次的结果是什么样子的,到底有多少种结果。
请设计一个程序帮助老师。
最后输出各种情况的人名即可,一行一种情况,每种情况的名字按照报名即输入顺序排序。
输入描述
输入第一行包含一个整数 NN。
接下来 NN 行每行包含一个字符串 SiSi,表示人名。
1≤N≤101≤N≤10,∑i=1N∣Si∣≤102i=1∑N∣Si∣≤102。
输出描述
输出共若干行,每行输出各种情况的人名。一行一种情况,每种情况的名字按照报名即输入顺序排序。
输入输出样例
示例
输入
3 xiaowang xiaoA xiaoli
输出
xiaowang xiaoA xiaoli xiaowang xiaoli xiaoA xiaoA xiaowang xiaoli xiaoA xiaoli xiaowang xiaoli xiaowang xiaoA xiaoli xiaoA xiaowang
模版:
-
int n; //共计N个数 int order[20]; bool chosen[20]; void calc(int k) { if (k == n + 1) { for (int i = 1; i <= n; i++) cout << order[i] << " "; puts(""); return; } for (int i = 1; i <= n; i++) { if (chosen[i]) continue; order[k] = i; chosen[i] = 1; calc(k + 1); chosen[i] = 0; order[k] = 0; } } int main() { cin >> n; calc(1); }
代码:
-
#include <iostream> #include <vector> using namespace std; int n; //共计N个数 vector<string> name; int order[20]; bool chosen[20]; void calc(int k) { if (k == n + 1) { for (int i = 1; i <= n; i++) cout << name[order[i] - 1] << " "; puts(""); return; } for (int i = 1; i <= n; i++) { if (chosen[i]) continue; order[k] = i; chosen[i] = 1; calc(k + 1); chosen[i] = 0; order[k] = 0; } } int main() { cin >> n; for (int i = 0; i < n; i++) { string s; cin >> s; name.push_back(s); } calc(1); }