0
点赞
收藏
分享

微信扫一扫

NOIP(CSP-J)信息学奥赛_普及组第十四课--穷举

洛茄 2022-04-01 阅读 221
c++

文章目录


14、穷举

一、什么是穷举

穷举:列举所有的可能的数据,判断哪些数满足条件!

二、单循环穷举

1015:【入门】鸡兔同笼问题

思路:循环鸡可能的只数范围,看该范围内当鸡为多少只时是满足题目要求的!

//i代表鸡的总数
循环(鸡的只数范围i = 1~49{
如果(有i只鸡,有50-i只兔,腿的总数满足160{
        输出鸡和兔的只数;
    }
}
1491*2+49*4==160
2482*2+48*4==160
3473*2+47*4==160
450-ii*2+(50)*4==160
49149*2+1*4==160
/* 1015 - 【入门】鸡兔同笼问题
题目描述
鸡兔同笼问题:一个笼子里面有鸡若干只,兔若干只。共有头50个,共有腿160条。求鸡兔各多少只?(6.2.32)

输入
无
输出
两个整数,在一行。
鸡的只数 兔的只数 中间空格隔开!

来源
需要找规律的循环

标签
需要找规律的循环 */
#include <bits/stdc++.h>
using namespace std;
int main()
{
    //定义变量j,t分别代表鸡的只数和兔子的只数
    int j,t;
    for (j = 1; j <= 49; j++)
    {
        //兔子+鸡=50
        t = 50 - j;
        //当腿的数量=160,总只数=50,就输出j,t
        if ((2 * j + 4 * t) == 160)
        {
            cout << j << " " << t << endl;
        }
    }
    return 0;
}

1351:【入门】买公园门票

思路:循环(穷举)成人可能的人数范围,在有i个成人的情况下,买完成人票剩余的金
额如果是儿童票单价的倍数,说明该组数据是符合条件的。

穷举方法:

成人人数剩余金额方案是否可行?
140-1*8=3632不是3的倍数,不可行
240-2*8=2424是3的倍数,可行
/* 1351 - 【入门】买公园门票
题目描述
某公园门票价格为:成人票8元/张,儿童票3元/张;某旅游团来公园游玩,该团内有成人和儿童(成人和儿童都有),共花了40元买门票,
请你分别计算出成人和儿童可能的人数,按照成人从少到多,儿童从多到少的规律数出结果。(7.2)

输入
无
输出
若干行,每行2个整数用空格隔开,分别代表成人和儿童可能的人数(成人从少到多,儿童从多到少)

来源
需要找规律的循环
标签
需要找规律的循环 */
#include <bits/stdc++.h>
using namespace std;
int main()
{
    /*
    思路:
    i =循环成人票可能的范围 1 ~ (40- 3) / 8
    买了 i张成人票的情况下,剩余的钱必须是儿童票单价的倍数
    */

    // i代表成人票的购买数量,x代表买了 i张成人票剩余的金额
    int i, x;
    //成人票最少1张,最多(40-3)/8张(因为至少留下买1张儿童票的钱)
    for (i = 1; i <= (40 - 3) / 8; i++)
    {
        //计算剩余金额
        x = 40 - i * 8;
        if (x % 3 == 0)
        {
            cout << i << " " << x / 3 << endl;
        }
    }
}

1016:【入门】买小猫小狗

/* 1016 - 【入门】买小猫小狗
题目描述
某动物饲养中心用X元专款购买小狗(每只A元)和小猫(每只B元)两种小动物。
要求专款专用,(至少猫狗各一),正好用完。请求出方案的总数。如没有请输出0。

输入
输入一行,只有三个整数.分别为X,A,B. ( 100 < X < 32768; 1 <= A, B <= 100 )
输出
输出只有一行(这意味着末尾有一个回车符号),包括1个整数。

样例
输入复制
1700 31 21
输出复制
3
来源
需要找规律的循环
标签
需要找规律的循环 */
#include <bits/stdc++.h>
using namespace std;
int main()
{
    /*
    共x元,小狗a元/只,小猫b元/只
    至少猫狗各一,正好用完*/
    int x, a, b, y, i; // y代表买了i只小狗剩余的钱
    int c = 0;         //计数的变量(count)
    cin >> x >> a >> b;
    //循环小狗可能的只数范围
    for (i = 1; i <= (x - b) / a; i++)
    {
        //计算买了i只小狗剩余的金额
        y = x - i * a;
        //如果剩余的金额是小猫单价的倍数,则方案成立
        if (y % b == 0)
        {
            // cout << i << " " << y / b << endl;
            c = c + 1;
        }
    }
    cout << c << endl;
}

代码中的y=x-i*a, 可以换成x=x-i*a吗

看看这样的解法:

//A狗单价,B猫单价,X金额
//循环小猫可能的只数
for(i=1;i<=(X-B)/A;i++){
//循环小狗可能的只数
    for(j=1;j<=(X-A)/B;j++){
//判断购买小猫+小狗的钱是否正好等于X
        if(A*i+B*j==X){
            n++;
        }
    }
}

1227:【入门】阿凡提的难题

条件一:钱要花完

条件二:两种碗都要买

条件三:两种碗的数量都得是偶数

/* 1227 - 【入门】阿凡提的难题
题目描述
阿凡提去集市上买餐具,财主正好在卖餐具,所以准备为难一下阿凡提;
财主的餐具有2种:大碗和小碗,财主和阿凡提说,你买我的碗,要花光你带的钱,
而且,两种碗都要买,买的两种碗的数量都得是偶数,
请你编程帮助阿凡提计算,可以有哪些购买的方案呢?

输入
三个整数,分别代表了阿凡提带的钱的数量,大碗的价格,小碗的价格!
输出
所有的购买方案,一行一个方案,先输出大碗的采购只数,再输出小碗的采购只数!

样例
输入复制
100 20 10
输出复制
2 6
4 2

来源
需要找规律的循环
标签
需要找规律的循环 */

#include <bits/stdc++.h>
using namespace std;
int main()
{
    /* 花完所有的钱,两种碗都要买,两种碗的数量都是偶数 */
    // q:阿凡提的总金额,x:买了 i只大碗剩余的钱
    // big:大碗单价,small:小碗单价
    int q, big, small, x, i;
    cin >> q >> big >> small;
    //循环大碗可能的只数范围(1~(q-2*small)/big)
    for (i = 2; i <= (q - 2 * small) / big; i = i + 2)
    {
        //计算买了 i只大碗剩余的钱
        x = q - i * big;
        //如果剩余的钱是小碗单价的倍数,且买到小碗的数量是偶数
        if (x % small == 0 && x / small % 2 == 0)
        {
            cout << i << " " << x / small << endl;
        }
    }
    return 0;
}

四、可选作业

1349:【入门】植树的人数

1396:【入门】开学大采购

1394:【入门】恐龙园买玩具

1220:【入门】买糕点

五、嵌套循环穷举

1022:【入门】百钱百鸡问题

/* 1022 - 【入门】百钱百鸡问题
题目描述
用100元钱买100只鸡,公鸡,母鸡,小鸡都要有。公鸡5元1只,母鸡3元1只,小鸡1元3只。请问公鸡,母鸡,小鸡各应该买多少只?

输入
无
输出
每种买法占一行,由3个数组成,顺序为 公鸡数 母鸡数 小鸡数。每个数字空格隔开。
输出时,按公鸡数从少到多,母鸡数从多到少的顺序输出,本题符合条件的第一组解为:4 18 78。

来源
需要找规律的循环
标签
需要找规律的循环 */

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, x, y;
    //公鸡可能的只数范围
    for (i = 1; i <= (100 - 3 - 1) / 5; i++)
    {
        //买完公鸡剩余的钱
        x = 100 - i * 5;
        //循环x元能买到的母鸡的范围
        for (j = 1; j <= (x - 1) / 3; j++)
        {
            //买完i只公鸡,j只母鸡剩余的钱
            y = x - j * 3;
            if (i + j + y * 3 == 100)
            {
                cout << i << " " << j << " " << y * 3 << endl;
            }
        }
    }
}

六、课堂练习

1025:【入门】兑换硬币

/* 1025 - 【入门】兑换硬币
题目描述
用一张一元票换1分、2分和5分的硬币,每种至少一枚, 问有几种换法?

输入
无
输出
输出只有一行(这意味着末尾有一个回车符号),包括1个整数。

来源
需要找规律的循环
标签
需要找规律的循环 */

#include <bits/stdc++.h>
using namespace std;
int main()
{
    /*
    1元=10角=100分
    循环1分可能的数量范围,用剩余的钱去换2分(循环2分数量范围)
    */
    int i, j, x, y;
    int c = 0; //计数器
    //循环1分可能的数量范围
    //循环1分可能的数量范围
    for (i = 1; i <= 100 - 2 - 5; i++)
    {
        //换完1分剩余的钱
        x = 100 - i;
        //用×分去换2分
        for (j = 1; j <= (x - 5) / 2; j++)
        {
            //计算换完1分和2分剩余的钱
            y = x - j * 2;
            //用y分去换5分
            if (y % 5 == 0)
            {
                cout<<i<<" "<<j<<" "<<y/5<<endl;
                c++;
            }
        }
    }
    cout << c << endl;
}

1024:【入门】购买文具

/* 1024 - 【入门】购买文具
题目描述
新学年就要开始了,爸爸把N元钱给了小青,让他购买一批文具,并作了以下要求:
只能买圆珠笔、铅笔和铅笔芯,并且每样至少买一支,总数要超过30支,而且钱要全部花完。
当小青去到文具店时,发现圆珠笔8角钱一支、铅笔2角钱一支、铅笔芯1角钱一支。
小青怎么买才能符合爸爸的要求呢?请你编个程序帮他算出符合购买要求的所有方案总数。

输入
一个整数N,表示购买文具一共的元数。(1 <= N <= 50)
输出
一个整数,即符合购买要求的所有方案总数。

样例
输入
8
输出
135

来源
需要找规律的循环
标签
需要找规律的循环 */

#include <bits/stdc++.h>
using namespace std;
int main()
{
    /*
    N元钱每样至少买一支总数要超过30支而且钱要全部花完
    圆珠笔8角钱一支、铅笔2角钱一支、铅笔芯1角钱一支*/
    int n, i, j, x, y;
    int c = 0; //方案总数
    cin >> n;
    n = n * 10; //将单位元换算为角
    //循环圆珠笔可能的购头数量范围
    for (i = 1; i <= (n - 2 - 1) / 8; i++)
    {
        //计算买完圆珠笔剩余的钱
        x = n - i * 8;
        //用 x 角去购买铅笔
        for (j = 1; j <= (x - 1) / 2; j++)
        {
            //计算买完圆珠笔和铅笔剩余的钱
            y = x - j * 2;
            //如果圆珠笔+铅笔+铅笔芯总数超过30支、
            if (i + j + y > 30)
            {
                c++;
            }
        }
    }
    cout << c << endl;
}

七、作业

1249:【入门】搬砖问题

1250:【入门】马克思手稿的问题

1076:【入门】桐桐的计算

1342:【入门】怎样种树?

1077:【入门】桐桐去购物

八、规律类穷举

1251:【入门】四个人的年龄求解

1086:【入门】姐妹数对

1350:【入门】纸盒的最大体积是多少?

九、可选作业

1083:【基础】回文数

1013:【入门】一个六位数

1082:【入门】猴子吃桃子


代码参考:

https://gitee.com/huimutan/OI/tree/master/oj.czos.cn/basics

举报

相关推荐

0 条评论