文章目录
- 一、前言
- 二、问题
- 问题:1022. 百钱百鸡问题
- 问题:1024. 购买文具
- 问题:1249. 搬砖问题
- 问题:1250. 马克思手稿的问题
- 问题:1342. 怎样种树?
- 三、感谢
一、前言
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
本章节主要对嵌套穷举的题目进行讲解,包括《1022. 百钱百鸡问题》《1024. 购买文具》《1249. 搬砖问题》《1250. 马克思手稿的问题》《1342. 怎样种树?》题目。
二、问题
问题:1022. 百钱百鸡问题
类型:嵌套穷举
题目描述:
用 100 元钱买 100 只鸡,公鸡,母鸡,小鸡都要有。
公鸡 5 元 1 只,母鸡 3 元 1 只,小鸡 1 元 3 只。
请问公鸡,母鸡,小鸡各应该买多少只?
输入:
无。
输出:
每种买法占一行,由 3 个数组成,顺序为 公鸡数 母鸡数 小鸡数。每个数字空格隔开。
输出时,按公鸡数从少到多,母鸡数从多到少的顺序输出,本题符合条件的第一组解为: 4 18 78 。
样例:
输入:
输出:
1.分析问题
- 已知:用 100 元钱买 100 只鸡,公鸡 5 元 1 只,母鸡 3 元 1 只,小鸡 1 元 3 只。
- 未知:找出所有解:公鸡,母鸡,小鸡各应该买多少只?
- 关系:公鸡,母鸡,小鸡都要有,按公鸡数从少到多,母鸡数从多到少的顺序输出。
2.定义变量
- 定义变量 g 表示公鸡数量,m 表示母鸡数量,x 表示小鸡数量,其中 g 初始化为 1。
//二、定义变量(已知、未知、关系)
int g=1,m,x;
3.输入数据
无。
4.数据计算
- 外层循环遍历所有可能的公鸡数量 g,其中 g 的范围是从 1 到 (100−3−1)/5(即在剩余金额允许的情况下最多能买多少公鸡)。
- 对于每个公鸡数量 g,计算可能的母鸡数量 m。
- 内层循环遍历所有可能的母鸡数量 m,其中 m 的范围是从 1 到初始计算的 m 值(即在剩余金额允许的情况下最多能买多少母鸡)。
- 对于每个母鸡数量 m,计算小鸡数量 x。
- 检查公鸡、母鸡和小鸡的总数量是否为 100。如果满足条件,输出公鸡数量 g、母鸡数量 m 和小鸡数量 x。
//四、根据关系计算
for(;g<=(100-3-1)/5;g++){
m=(100-5*g-1)/3;
for(;m>=1;m--){
x=3*(100-5*g-3*m);
//五、输出未知
if(g+m+x==100){
cout<<g<<" "<<m<<" "<<x<<"\n";
}
}
}
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 一、分析问题
// 已知:用 100 元钱买 100 只鸡,公鸡 5 元 1 只,母鸡 3 元 1 只,小鸡 1 元 3 只。
// 未知:找出所有解:公鸡,母鸡,小鸡各应该买多少只?
// 关系: 公鸡,母鸡,小鸡都要有,按公鸡数从少到多,母鸡数从多到少的顺序输出。
// 二、定义变量(已知、未知、关系)
int g = 1, m, x; // g: 公鸡数量, m: 母鸡数量, x: 小鸡数量
// 四、根据关系计算
// 通过循环遍历所有可能的公鸡数量 g
for (; g <= (100 - 3 - 1) / 5; g++) { // 确保剩余金额足够买至少一只母鸡和一只小鸡
m = (100 - 5 * g - 1) / 3; // 根据剩余金额计算可能的母鸡数量
// 内层循环遍历所有可能的母鸡数量 m
for (; m >= 1; m--) { // 确保母鸡数量至少为 1
x = 3 * (100 - 5 * g - 3 * m); // 根据剩余金额计算小鸡数量
// 五、输出未知
if (g + m + x == 100 ) { // 确保总数量为 100
cout << g << " " << m << " " << x << "\n"; // 输出公鸡数量、母鸡数量和小鸡数量
}
}
}
return 0;
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1024. 购买文具
类型:嵌套穷举
题目描述:
新学年就要开始了,爸爸把N元钱给了小青,让他购买一批文具,并作了以下要求:只能买圆珠笔、铅笔和铅笔芯,并且每样至少买一支,总数要超过30支,而且钱要全部花完。
当小青去到文具店时,发现圆珠笔8角钱一支、铅笔2角钱一支、铅笔芯1角钱一支。小青怎么买才能符合爸爸的要求呢?请你编个程序帮他算出符合购买要求的所有方案总数。
输入:
一个整数N,表示购买文具一共的元数。(1 <= N <= 50)
输出:
一个整数,即符合购买要求的所有方案总数。
样例:
输入:
8
输出:
135
1.分析问题
- 已知:N元钱,圆珠笔8角钱一支、铅笔2角钱一支、铅笔芯1角钱一支。
- 未知:符合购买要求的所有方案总数。
- 关系:每样至少买一支,总数要超过30支,而且钱要全部花完。
2.定义变量
- 定义变量 n 表示总金额(以角为单位),y 表示圆珠笔数量,qb 表示铅笔数量,qbx 表示铅笔芯数量,c 表示方案总数,其中 y 初始化为 1,c 初始化为 0。
//二、定义变量(已知、未知、关系)
int n,y=1,qb,qbx,c=0;
3.输入数据
- 从标准输入读取总金额 N。
- 将金额放大10倍,方便计算。
//三、输入已知
cin>>n;
n*=10;
4.数据计算
- 外层循环遍历所有可能的圆珠笔数量 y,其中 y 的范围是从 1 到 (n−2−1)/8(即在剩余金额允许的情况下最多能买多少圆珠笔)。
- 对于每个圆珠笔数量 y,计算可能的铅笔数量 qb。
- 内层循环遍历所有可能的铅笔数量 qb,其中 qb 的范围是从 1 到初始计算的 qb 值(即在剩余金额允许的情况下最多能买多少铅笔)。
- 对于每个铅笔数量 qb,计算铅笔芯数量 qbx。
- 检查圆珠笔、铅笔和铅笔芯的总数量是否超过 30 支。如果满足条件,方案总数 c 加 1。
//四、根据关系计算
for(;y<=(n-2-1)/8;y++){
qb=(n-8*y-1)/2;
for(;qb>=1;qb--){
qbx=n-8*y-2*qb;
if(y+qb+qbx>30) ++c;
}
}
5.输出结果
- 输出方案总数 c。
//五、输出未知
cout<<c;
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 一、分析问题
// 已知:N元钱, 圆珠笔 8 角钱一支、铅笔 2 角钱一支、铅笔芯 1 角钱一支。
// 未知:符合购买要求的所有方案总数。
// 关系: 每样至少买一支,总数要超过 30 支,而且钱要全部花完。
// 二、定义变量(已知、未知、关系)
int n, y = 1, qb, qbx, c = 0; // n: 总金额(以角为单位),y: 圆珠笔数量, qb: 铅笔数量, qbx: 铅笔芯数量, c: 方案总数
// 三、输入已知
cin >> n;
n *= 10; // 将金额转换为角
// 四、根据关系计算
// 通过循环遍历所有可能的圆珠笔数量 y
for (; y <= (n - 2 - 1) / 8; y++) { // 确保剩余金额足够买至少一支铅笔和一支铅笔芯
qb = (n - 8 * y - 1) / 2; // 根据剩余金额计算可能的铅笔数量
// 内层循环遍历所有可能的铅笔数量 qb
for (; qb >= 1; qb--) { // 确保铅笔数量至少为 1
qbx = n - 8 * y - 2 * qb; // 根据剩余金额计算铅笔芯数量
// 五、输出未知
if (y + qb + qbx > 30) { // 确保总数量超过 30 支
++c; // 符合条件,方案总数加 1
}
}
}
// 五、输出未知
cout << c; // 输出方案总数
return 0;
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1249. 搬砖问题
类型:嵌套穷举
题目描述:
36 块砖, 36 人搬。男搬 4 ,女搬 3 ,两个小儿抬一砖。
要求一次全搬完。问需男、女、小儿各若干?
注意:假设男、女、小孩都有,请按照男、女、小孩的顺序输出所有可能的人数分配,每种人数分配方案占 1 行,每个数字空格隔开。
输入:
无。
输出:
所有可能的人数分配方案,按照由小到大输出。
样例:
输入:
输出:
1.分析问题
- 已知:36 块砖, 36 人搬。男搬 4 ,女搬 3 ,两个小儿抬一砖。
- 未知:要求一次全搬完。问需男、女、小儿各若干?输出所有可能的人数分配。
- 关系:男、女、小孩都有,按照男、女、小孩的顺序由小到大输出。
2.定义变量
- 定义变量 m 表示男性人数,w 表示女性人数,c 表示小孩人数,其中 m 和 w 初始化为 1。
//二、定义变量(已知、未知、关系)
int m=1,w,c;
3.输入数据
无。
4.数据计算
- 外层循环遍历所有可能的男性人数 m,其中 m 的范围是从 1 到 (36−3−1)/4(即在剩余人数允许的情况下最多能有多少男性)。
- 内层循环遍历所有可能的女性人数 w,其中 w 的范围是从 1 到 (36−m∗4−1)/3(即在剩余人数允许的情况下最多能有多少女性)。
- 对于每个女性人数 w,计算小孩数量 c。
- 检查男性、女性和小孩的总人数是否为 36。如果满足条件,输出男性人数 m、女性人数 w 和小孩人数 c。
//四、根据关系计算
for(;m<=(36-3-1)/4;m++){
for(w=1;w<=(36-m*4-1)/3;w++){
c=(36-m*4-w*3)*2;
//五、输出未知
if(m+w+c==36){
cout<<m<<" "<<w<<" "<<c<<"\n";
}
}
}
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 一、分析问题
// 已知:36 块砖,36 人搬。男搬 4,女搬 3,两个小孩抬 1 块砖。
// 未知:要求一次全搬完。问需男、女、小孩各若干?输出所有可能的人数分配。
// 关系: 男、女、小孩都有,按照男、女、小孩的顺序由小到大输出。
// 二、定义变量(已知、未知、关系)
int m = 1, w, c; // m: 男性人数, w: 女性人数, c: 小孩人数
// 四、根据关系计算
// 通过循环遍历所有可能的男性人数 m
for (; m <= (36 - 3 - 1) / 4; m++) { // 确保剩余人数足够搬至少一位女性和两位小孩
// 内层循环遍历所有可能的女性人数 w
for (w=1; w <= (36 - m * 4 - 1) / 3; w++) { // 确保剩余人数足够搬至少两位小孩
c = (36 - m * 4 - w * 3) * 2; // 根据剩余人数计算小孩数量
// 五、输出未知
if (m + w + c == 36) { // 确保总人数为 36
cout << m << " " << w << " " << c << "\n"; // 输出男性人数、女性人数和小孩人数
}
}
}
return 0;
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1250. 马克思手稿的问题
类型:嵌套穷举
题目描述:
马克思手稿中有一道趣味数学题:有 30 个人,其中可能有男人、女人和小孩,在一家饭馆里吃饭共花了 50 先令。
假设每个男人各花 3先令,每个女人各花 2 先令,每个小孩各花 1先令。
问男人、女人和小孩各有几人?(注意:不一定男人、女人、小孩都有)
输入:
无。
输出:
每行 3 个数,按照男人、女人、小孩的顺序,由小到大依次输出所有可能的人数方案(男人、女人、小孩其中某些人的数量可以为 0 )
样例:
输入:
输出:
1.分析问题
-
已知: 有 30 个人,花了 50 先令,每个男人各花 3先令,每个女人各花 2 先令,每个小孩各花 1先令。
-
未知:问男人、女人和小孩各有几人?按照男人、女人、小孩的顺序,由小到大依次输出所有可能的人数方案。
-
关系:男人、女人、小孩其中某些人的数量可以为 0 。
2.定义变量
- 定义了三个整型变量 m, w, 和 c 分别表示男人、女人和小孩的数量。
//二、定义变量(已知、未知、关系)
int m=0,w,c;
3.输入数据
无。
4.数据计算
-
外层循环遍历所有可能的男人数量,从 0 到 30。
-
内层循环遍历所有可能的女人数量,考虑到总人数不能超过 30 人,因此女人的数量最多为 30 - m。
-
根据当前的男人和女人数量计算小孩的数量。
-
判断当前组合是否使得总花费等于 50 先令。如果是,则输出男人、女人和小孩的数量。
//四、根据关系计算
for(;m<=30;++m){
for(w=0;w<=30-m;++w){
c=30-m-w;
//五、输出未知
if(50==m*3+w*2+c){
cout<<m<<" "<<w<<" "<<c<<"\n";
}
}
}
完整代码如下:
#include <bits/stdc++..h> // 包含所有标准库
using namespace std;
int main() {
// 定义变量
int m = 0, w, c; // m 表示男人数量,w 表示女人数量,c 表示小孩数量
// 使用嵌套循环来尝试所有可能的组合
for (; m <= 30; ++m) { // 循环遍历所有可能的男人数量
for (w = 0; w <= 30 - m; ++w) { // 循环遍历所有可能的女人数量
c = 30 - m - w; // 剩下的人数就是小孩的数量
// 检查当前组合是否满足总花费为 50 先令
if (50 == m * 3 + w * 2 + c) {
// 如果满足条件,则输出当前组合
cout << m << " " << w << " " << c << "\n";
}
}
}
return 0; // 正常退出程序
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1342. 怎样种树?
类型:嵌套穷举
题目描述:
公园准备在小山上种桃树、梨树、苹果树,为了美观,总共准备种n棵树( n≥6 且 n 一定是 6 的倍数),要求三种树都得有,且每种树的数量都得是偶数,桃树的数量不能比梨树的数量多,梨树的数量不能比苹果树的数量多。
请问有这三种树的数量分别有哪些可能的组合方法,从少到多分别数出桃树、梨树、苹果数可能的数量组合,每行 1 个方案。
输入:
一个整数n( n≥6 且是 6 的倍数)
输出:
若干行的可能的组合方案,每行 3 个数,分别代表桃树、梨树、苹果树的可能的方案。
样例:
输入:
18
输出:
2 2 14
2 4 12
2 6 10
2 8 8
4 4 10
4 6 8
6 6 6
1.分析问题
-
已知: 准备种n棵树,三种树都得有,且每种树的数量都得是偶数,桃树的数量不能比梨树的数量多,梨树的数量不能比苹果树的数量多。
-
未知: 请问有这三种树的数量分别有哪些可能的组合方法,从少到多分别数出桃树、梨树、苹果数可能的数量组合,每行 1 个方案。
2.定义变量
- 定义变量 n(总树的数量)、t(桃树数量)、l(梨树数量)和 p(苹果树数量)。
//二、定义变量(已知、未知、关系)
int n,t=2,l,p;
3.输入数据
- 读取用户输入的总树的数量。
//三、输入已知
cin>>n;
4.数据计算
- 外层循环遍历所有可能的桃树数量,从 2 开始每次增加 2,确保桃树数量始终是偶数且不超过总数的三分之一。
- 内层循环遍历所有可能的梨树数量,从当前桃树数量开始每次增加 2,确保梨树数量大于等于桃树数量,且不超过剩余树的一半。
- 计算苹果树的数量,输出当前组合。
//四、根据关系计算
for(;t<=n/3;t+=2){
for(l=t;l<=(n-t)/2;l+=2){
p=n-t-l;
//五、输出未知
cout<<t<<" "<<l<<" "<<p<<"\n";
}
}
完整代码如下:
#include <bits/stdc++.h> // 包含所有标准库
using namespace std;
int main() {
// 定义变量
int n, t = 2, l, p; // n 是总树的数量,t 表示桃树数量,l 表示梨树数量,p 表示苹果树数量
// 输入已知的总树的数量
cin >> n;
// 使用嵌套循环来尝试所有可能的组合
for (; t <= n / 3; t += 2) { // 循环遍历所有可能的桃树数量,从 2 开始每次增加 2
for (l = t; l <= (n - t) / 2; l += 2) { // 循环遍历所有可能的梨树数量,从当前桃树数量开始,每次增加 2
p = n - t - l; // 剩下的数量就是苹果树的数量
// 输出当前组合
cout << t << " " << l << " " << p << "\n";
}
}
return 0; // 正常退出程序
}
三、感谢
如若本文对您的学习或工作有所启发和帮助,恳请您给予宝贵的支持——轻轻一点,为文章点赞;若觉得内容值得分享给更多朋友,欢迎转发扩散;若认为此篇内容具有长期参考价值,敬请收藏以便随时查阅。
每一次您的点赞、分享与收藏,都是对我持续创作和分享的热情鼓励,也是推动我不断提供更多高质量内容的动力源泉。期待我们在下一篇文章中再次相遇,共同攀登知识的高峰!
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》