文章目录
前言
穷举法是一种基础而实用的算法策略,它通过逐一检查所有可能的情况来寻找问题的解。这种方法特别适用于问题规模较小或解决方案数量有限的情况。尽管穷举法可能不是最高效的算法,但它保证能找到问题的正确答案,尤其适合于初学者理解和实践。
本章将介绍穷举法的基本概念、步骤以及通过几个具体的例子来演示如何使用穷举法解决问题。
学习路线:C++从入门到NOI学习路线
学习大纲:C++全国青少年信息学奥林匹克竞赛(NOI)入门级-大纲
一、概念
1.导入
今天我们要来学习穷举。
当然不是这个“穷举”啦,穷举法是一种基本的算法策略,它通过逐一检查所有可能的情况来寻找问题的解。
可能这么说,大家无法理解这个概念。
你有一个密码箱,密码是一个三位数,每一位都是从0到9的数字。
箱子里面有你想要用的东西,但是很巧的是你把密码忘记了。
这种情况下,我们怎样才能打开这个锁呢?
由于我们不知道密码是什么,那我们首先想要的方法就是尝试所有的可能性。也就是说,从000开始,一直试到999,总共有1000种可能的组合。
你们肯定不会想到下面这种方法的。
这种尝试000,如果不行,就尝试001;如果001也不行,就尝试002,以此类推;继续尝试,直到找到正确的密码为止的方法就是穷举法。
2.概念
穷举法:通过尝试所有可能的选项来解决问题的方法。
优化:当有额外信息时,可以通过优化搜索范围来提高解决问题的效率。
穷举法的步骤如下:
-
确定问题的范围:根据问题的要求,确定需要尝试的数值范围。
-
使用循环进行穷举:使用循环结构(如for循环)遍历范围内的每个数值。
-
将数值带入问题中进行尝试:将当前数值带入问题中,判断是否满足问题的条件。
-
如果满足条件,输出结果或进行其他操作:如果当前数值满足问题的条件,可以输出该数值作为问题的解,或进行其他操作。
-
继续循环直到穷举完所有可能的解。
二、例题讲解
1. 简单穷举
问题:1015. 鸡兔同笼问题
类型:简单穷举
题目描述:
鸡兔同笼问题:一个笼子里面有鸡若干只,兔若干只。共有头 50 个,共有腿 160 条。求鸡兔各多少只?
输入:
无。
输出:
两个整数,在一行。
鸡的只数 兔的只数。
中间空格隔开!
样例:
输入:
输出:
1.分析问题
- 已知:头50 个、腿有160个。
- 未知:鸡,兔各多少。
- 关系:鸡 头1腿2,兔 头1腿4。
2.定义变量
根据分析的已知,未知按需要定义变量。
j:鸡
t:兔
//定义鸡、兔的数量。
int j=0,t=0;
3.输入数据
无。
4.数据计算
4.1 确定问题的范围:根据问题的要求,确定需要尝试的数值范围。
t + j = 50,t * 2 + j * 4 = 140
4.2 使用循环进行穷举:使用循环结构(如for循环)遍历范围内的每个数值。
4.3 将数值带入问题中进行尝试:将当前数值带入问题中,判断是否满足问题的条件。
//四、数据计算
while(j*2+(50-j)*4!=160){
j++;
}
4.4 如果满足条件,输出结果或进行其他操作。
t=50-j;
cout<<j<<" "<<t<<endl;
完整代码如下:
#include<iostream>
using namespace std;
int main(){
// 一、分析问题
// 已知:笼子里有50只动物(鸡和兔),这些动物总共有160条腿。
// 未知:鸡和兔各有多少只?
// 二、数据定义
// 定义鸡、兔的数量。
int j = 0, t = 0;
// 三、数据输入
// (在这个简单的示例中,数据已经作为常量给出,无需用户输入)
// 四、数据计算
// 使用while循环来穷举所有可能的鸡的数量
// 每次循环增加鸡的数量,并检查当前的腿总数是否等于160
while (j * 2 + (50 - j) * 4 != 160) {
j++; // 增加鸡的数量
}
t = 50 - j; // 兔子的数量为总数减去鸡的数量
// 五、输出结果
cout << j << " " << t << endl; // 输出鸡和兔的数量
return 0; // 主函数结束,返回0表示程序正常退出
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1351. 买公园门票
类型:简单穷举
题目描述:
某公园门票价格为:成人票 8 元 / 张,儿童票 3 元 / 张;某旅游团来公园游玩,该团内有成人和儿童(成人和儿童都有),共花了 40 元买门票。
请你分别计算出成人和儿童可能的人数,按照成人从少到多,儿童从多到少的规律数出结果。
输入:
无
输出:
若干行,每行 2 个整数用空格隔开,分别代表成人和儿童可能的人数。(成人从少到多,儿童从多到少)
样例:
输入:
输出:
1.分析问题
- 已知:成人票 8 元 / 张,儿童票 3 元 / 张;共花了 40 元买门票。
- 未知:成人和儿童的人数。
- 关系:成人从少到多,儿童从多到少。
2.定义变量
无。
3.输入数据
无。
4.数据计算
4.1 确定问题的范围:根据问题的要求,确定需要尝试的数值范围。
成人票:最少1张,最多(40-3)/8张,要保证有一张儿童票。
儿童票:最少1张,最多(40-8)/3张,要保证有一张成人票。
4.2 使用循环进行穷举:使用循环结构(如for循环)遍历范围内的每个数值。
i:成人票数量。
for(int i=1;i<=(40-3)/8;i++){
}
4.3 将数值带入问题中进行尝试:将当前数值带入问题中,判断是否满足问题的条件。
j:购买成人票后剩余钱数。
如果j%3==0,说明剩余的钱刚好能买整数个儿童票,符合题意。
//四、数据计算
for(int i=1;i<=(40-3)/8;i++){
int j=40-8*i;
if(j%3==0){
}
}
4.4 如果满足条件,输出结果或进行其他操作。如果当前数值满足问题的条件,可以输出该数值作为问题的解,或进行其他操作。
//四、数据计算
for(int i=1;i<=(40-3)/8;i++){
int j=40-8*i;
if(j%3==0){
//五、输出结果
cout<<i<<" "<<j/3;
}
}
4.5 继续循环直到穷举完所有可能的解。
完整代码如下:
#include<iostream>
using namespace std;
int main(){
// 一、分析问题
// 1. 已知:成人票 8 元 / 张,儿童票 3 元 / 张;共花了 40 元买门票。
// 2. 未知:成人和儿童的人数。
// 二、数据定义
// 定义成人票和儿童票的数量。
// 由于成人票价较高,我们从成人票开始穷举。
// 三、数据输入
// (在这个简单的示例中,数据已经作为常量给出,无需用户输入)
// 四、数据计算
// 使用for循环来穷举所有可能的成人票数量
// 每次循环增加成人票的数量,并检查剩余金额是否能被3整除
for(int i = 1; i <= (40 - 3) / 8; i++) {
// 穷举成人票数量
int j = 40 - 8 * i; // 剩余金额
if (j % 3 == 0) {
// 如果剩余金额能被3整除
// 五、输出结果
cout << i << " " << j / 3 << endl; // 输出成人和儿童的人数
}
}
return 0; // 主函数结束,返回0表示程序正常退出
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1016. 买小猫小狗
类型:简单循环
题目描述:
某动物饲养中心用 X 元专款购买小狗(每只 A 元)和小猫(每只B 元)两种小动物。
要求专款专用,(至少猫狗各一),正好用完。
请求出方案的总数。如没有请输出 0 。
输入:
输入一行,只有三个整数.分别为 X,A,B。( 100<X<32768,1≤A≤100,1≤B≤100 )
输出:
输出只有一行(这意味着末尾有一个回车符号),包括 1 个整数。
样例:
输入:
1700 31 21
输出:
3