题目传送门
一、无脑大循环
#include<bits/stdc++.h>
using namespace std;
vector<string> v1;
int main() {
int a, b, c, d, e, f, g, h, i, j, k, l = 0;
cin >> k;
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 == k)
v1.push_back(to_string(a) + " " +
to_string(b) + " " +
to_string(c) + " " +
to_string(d) + " " +
to_string(e) + " " +
to_string(f) + " " +
to_string(g) + " " +
to_string(h) + " " +
to_string(i) + " " +
to_string(j));
cout << v1.size() << endl;
for (int i = 0; i < v1.size(); i++)
cout << v1[i] << endl;
return 0;
}
二、深度优先搜索
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
//方案数量,预计,注意,此处可不是n的数据上限,而是可能的方案数量,尽量开大防止出错,黄海就因为开小了挂掉!
const int M = 20; //配料的数量,本题目是10,为了开大一点数组,加了10
int a[N][M]; //保存所有可行的方案,描述,第i种方案,放过二维的第一个格子0,第二个格子1表示i种方案中第一个配料用多少克
int path[M]; //记录当前正在计算的方案.本题经验,数组开小了,会出错n值错乱的诡异问题!!!!描述当前方案每一种配料用多少克
/**
C++语言中数组越界访问系统不会给出任何的提示,程序员可以超出数组边界进行读/写从而造成内存的混乱,
而这种错误对初学者来说是很容易出现的、而又偏偏是很难调试的,因为系统不会给出错误的提示,所以就这样使用数组是不安全的。
*/
/**
对比暴力无脑大模拟,dfs的使用范围更广,很好理解,比如我们不知道要多少轮,轮次数需要输入进来,我们就没有办法预先控制循环的层数,
而dfs天生就是可以处理不定层数的!
*/
int n, cnt; //美味值,可行方案数量
/**
* 假设我们在面临一种通用的场景,也就是通常说的“一般性场景”
* (1)我们正在准备放入第step件调料,目前的情况是没放此种调料之前的美味值是sum
* (2)第step件调料,我们可以选择放入1,2,3三种数量,需要用循环把这些都尝试一遍。
* (3)如果我们选择完了数量i之后,我们需要继续向下一种调料出发,但情况已经发生了变化,变成处理第
* step+1件调料,同时总和也变成了sum+i
* (4)当处理完第10件调料后,也就是step=9(因为step是从0开始的)时,再向下就是递归出口,在这里判断是不是一组可行解。
*/
//step为第几种调料,sum目前的配料之和
void dfs(int step, int sum) {
if (step == 11) { //当10种调料都分析完了
//如果配料之和等于输入值;
//使用memcpy更简单,参数:目标数组,源数组,长度
if (sum == n)memcpy(a[cnt++], path, sizeof path);
//不管等不等,都需要返回了,递归的出口
return;
}
//在当前step下,就是在讨论某一种调料时,面临三种选择,1,2,3
for (int i = 1; i <= 3; i++) {
path[step] = i; //第step种调料的配料为i
dfs(step + 1, sum + i); //递归,对下一种调料做同样的分析
}
}
int main() {
cin >> n;
//从第1步开始,目前总和是0
dfs(1, 0);
//输出方案个数
cout << cnt << endl;
//再输出具体的方案
if (cnt > 0) {
for (int i = 0; i < cnt; i++) {
for (int j = 1; j <= 10; j++)
cout << a[i][j] << " ";
cout << endl;
}
}
return 0;
}