c++枚举例题
如果你不知道什么是枚举:传送门
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有\(10\)种配料(芥末、孜然等),每种配料可以放\(1\)到\(3\)克,任意烤鸡的美味程度为所有配料质量之和。现在, Hanke 想要知道,如果给你一个美味程度\(n\),请输出这\(10\)种配料的所有搭配方案。
输入格式
一个正整数\(n\),表示美味程度。\(n \leq 5000\)输出格式
第一行,方案总数
第二行至结束,\(10\)个数,表示每种配料所放的质量,按字典序排列。
如果没有符合要求的方法,就只要在第一行输出一个\(0\)。输入样例
11输出样例
10
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 2 1 1 1 1
1 1 1 1 2 1 1 1 1 1
1 1 1 2 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1
1 2 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1
思路:这是一个典型的暴力枚举题,因为数据范围很小,我们只需要十个嵌套for循环,枚举每一种可能即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int INF = 0x7fffffff;
int main() {
int a, b, c, d, e, f, g, h, i, j, n, res=0;
cin >> n;
for(a = 1; a <= 3; a++) {
for(b = 1; b <= 3; b++) {
for(c = 1; c <= 3; c++) {
for(d = 1; d <= 3; d++) {
for(e = 1; e <= 3; e++) {
for(f = 1; f <= 3; f++) {
for(g = 1; g <= 3; g++) {
for(h = 1; h <= 3; h++) {
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
if(a+b+c+d+e+f+g+h+i+j == n) {
res++;
}
}
}
}
}
}
}
}
}
}
}
cout << res << endl;
for(a = 1; a <= 3; a++) {
for(b = 1; b <= 3; b++) {
for(c = 1; c <= 3; c++) {
for(d = 1; d <= 3; d++) {
for(e = 1; e <= 3; e++) {
for(f = 1; f <= 3; f++) {
for(g = 1; g <= 3; g++) {
for(h = 1; h <= 3; h++) {
for(i = 1; i <= 3; i++) {
for(j = 1; j <= 3; j++) {
if(a+b+c+d+e+f+g+h+i+j == n) {
cout << a << " " << b << " ";
cout << c << " " << d << " ";
cout << e << " " << f << " ";
cout << g << " " << h << " ";
cout << i << " " << j << endl;
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
输入\(n,m,k\),输入一个\(n\times m\)的字符矩阵,输出其中可以让\(k\)人排成一排的空位数,行列皆可。\(n,m\leq 100, k < min(n,m)\)。
思路:题目中的数据范围很小,我们可以直接枚举,从每一个点开始,横向和竖向搜索\(k\)位,如果没有碰到任何障碍,答案加\(1\),当然我们需要特殊考虑当\(k=1\)时,横向和竖向是一样的,这相当于我们计算量两次,所以需要特判并输出答案\(/2\)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int INF = 0x7fffffff;
int n, m, k, res;
char ch[110][110];
int main(){
cin >> n >> m >> k;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> ch[i][j];
}
}
for(int i = 1; i <= n; i++){//横向判断
for(int j = 1; j <= m; j++){
if(ch[i][j] != '#'){
bool b = true;
for(int a = 0; a < k; a++){
if(ch[i][j+a] != '.'){
b = false;
break;
}
}
if(b) res++;
}
}
}
for(int i = 1; i <= n; i++){//竖向判断
for(int j = 1; j <= m; j++){
if(ch[i][j] != '#'){
bool b = true;
for(int a = 0; a < k; a++){
if(ch[i+a][j] != '.'){
b = false;
break;
}
}
if(b) res++;
}
}
}
if(k == 1) cout << res / 2 << endl;//特判当k=1
else cout << res << endl;
return 0;
}
某国法律规定,只要一个由\(N\times M\)个小方块组成的旗帜符合如下规则,就是合法的国旗。
- 从最上方若干行(至少一行)的格子全部是白色的;
- 接下来若干行(至少一行)的格子全部是蓝色的;
- 剩下的行(至少一行)全部是红色的;
现有一个棋盘状的布,分成了 \(N\) 行 \(M\) 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成该国国旗,方法是在一些格子上涂颜料,盖住之前的颜色。小a很懒,希望涂最少的格子,使这块布成为一个合法的国旗。
输入格式
第一行是两个整数\(N\),\(M\)。\(N,M \leq 50\)
接下来\(N\)行是一个矩阵,矩阵的每一个小方块是W(白),B(蓝),R(红)中的一个。输出格式
一个整数,表示至少需要涂多少块。
输入样例 输出样例
4 5 11
WRWRW
BWRWB
WRWRW
RWBWR
思路:我们知道数据范围很小,所以果断选择暴力枚举。根据题目,我们可以这样开三个数数组\(W[i],B[i],R[i]\)分别表示前\(i\)行涂成白、蓝、红需要的格子数。假设第\(1\)行到第\(i\)行是白色,第\(i+1\)行到第\(j\)行是蓝色,第\(j+1\)行到第\(n\)行是红色,则此时的需要涂的格子为\(W[i] + B[j]-B[i]+R[n]-R[j]\)。我们只需要枚举\(i,j\),取最小值即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int INF = 0x7fffffff;
int n, m, res = INF;
string str;
int W[55], B[55], R[55];
inline int check(char ch){
int res = 0;
for(int i = 0; i < m; i++){
if(str[i] != ch) res++;
}
return res;
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> str;
W[i] = W[i-1] + check('W');
B[i] = B[i-1] + check('B');
R[i] = R[i-1] + check('R');
}
for(int i = 1; i < n - 1; i++){
for(int j = i + 1; j < n; j++){
res = min(res,W[i]+B[j]-B[i]+R[n]-R[j]);
}
}
cout << res << endl;
return 0;
}
给你\(n\)根火柴棍,你可以拼出多少个形如\(A+B=C\)的等式?等式中的\(A\)、\(B\)、\(C\)是用火柴棍拼出的整数(若该数非零,则最高位不能是\(0\))。
注意:
- 加号与等号各自需要两根火柴棍
- 如果$A\neq B \(,则\)A+B=C\(与\)B+A=C\(视为不同的等式\)(A,B,C\geq 0)$。
- \(n\)根火柴棍必须全部用上
输入格式:一个整数\(n\)\((n \leq 24)\)。
输出格式:一个整数,能拼成的不同等式的数目。
思路:因为最多只有\(20\)根火柴用来拼三个数字,所以我们只需要记录\(1\)到\(1000\)内所有数字是用火柴数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int INF = 0x7fffffff;
int main()
{
int arr[2001]={6},n,src[10]={6,2,5,5,4,5,6,3,7,6},sum,i,j;
cin>>n;
for(i=1;i<=2000;i++)
{
j=i;
while(j>=1)
{
arr[i]+=src[j%10];
j/=10;
}
}
for(i=0;i<1000;i++)
for(j=0;j<1000;j++)
if(arr[i]+arr[j]+arr[i+j]+4==n) sum++;
cout<<sum<<endl;
return 0;
}