枚举算法基础 - 理解特简单!

枚举算法:

依赖于计算机的强大计算能力来穷尽每一种可能的情况,从而达到求解的目的。

一、九九乘法表

首先要知道是循环嵌套,那么外层 i 循环必定是决定多少行,内层 j 的循环决定了每行循环多少次,即内层决定列数。

先从简单模型入手:

当外层循环 i = 1 时,九九乘法表内层则是会从 1 遍历到 9.

当外层循环 i = 2 时,九九乘法表内层还是会从 1 遍历到 9.

......

则外层循环:

for (int i = 1 ; i <= 9 ; i++)
{
}

那内层循环也是会从1到9,简单一点,直接让 j <= i;

for (int i = 1 ; i <= 9 ; i++)
{
    for (int j = 1 ; j <= i ; j++)
    {
       //在这里输出 i 和 j 的乘积
    }

}

总体代码:

#include<iostream>
#include<iomanip> // 导入头文件,使用setw()设置输出的域宽
using namespace std;
int main()
{
    int row,column;
    for(row=1;row<=9;row++){
        for(column=1;column<=row;column++){
            cout<<column<<"*"<<row<<"="<<setw(2)<<column*row<<" ";
            //setw()只对紧接的输出有效
        }
        cout<<endl;
    }
}

二、鸡兔同笼问题

问题:有鸡兔同笼,上有三十五个头,下有九十四只足,请问鸡兔各几何?

输出:鸡的数量、兔的数量

----------------------------------------------------------------------------------------------------

解释:

首先搞清楚,鸡有 1 头 2 脚,兔有 1 头 4 脚。

列举所以可能出现的情况,判断哪些数满足条件

若有 1 只鸡,那么兔的数量 1 - 35 只,逐一测试

若有 2 只鸡,那么兔的数量 1 - 35 只,逐一测试

......

假设有 35 只鸡,那么兔的数量  1 - 35 只,逐一测试

这些情况中有一种会满足条件: 35 个头,94个脚。

在这里设置两个变量 i , j ,满足以下式子:

i + j = 35

2 * i + 4 * j = 94

#include<iostream>
using namespace std;

int main()
{
    //循环鸡头可能的范围
    for(int i = 1; i <= 35 ; i++)
    {
        //循环兔头可能的范围
        for(int j = 1 ; j <= 35 ; j++)
        {
            if( i + j == 35 && 2 * i + 4 * j == 94)
            {
                cout<<i<<" "<<j<<endl;
            }
        }
    }
    return 0;
}

这串代码循环计算了 35 * 35次,效率低。

优化算法:设置一个变量 i ,有 i 只鸡,则有 35 - i只兔子

头的数量:i + 35 - i = 35

脚的数量:2 * i + 4 * (35 - i) = 94

这样就只需要做一个for循环了(只循环35次):

#include<iostrean>
using namespace std;

int main()
{
    //循环鸡的头
    for(int i = 1; i <= 35; i++)
    {
        if( i * 2 + (35 - i) * 4 == 94)
        {
            cout<<i<<" "<<35-i<<endl;//此时的i为鸡头数量,35-i 为兔头数量
        }
    }
}

这是最佳优化了吗?不!还能继续

我们想一想,就目前来说,鸡和兔的脚都是偶数,可以除以二吧

除二后,鸡没脚了,每只兔子还剩两只脚。带入进去是 94 / 2 = 47.

这里的46就是兔子的和鸡的脚,那我们这46除以二了(鸡两条腿,兔四条腿),那46里面包含了35个头和多出来的脚,则多出来的脚就是兔子的数量。

为啥? -- 因为35个头里面已经包含了鸡和兔头了,所以多出来的数量可以理解为兔子另外的一对腿的数量。这样的话,47 - 35 的差值就是兔子的数量了

所以是兔子的数量就是12只,那么 35 - 12 = 23只是鸡的数量。

#include<iostream>
using namespace std;

int main()
{
    int chick,rab;
    int head = 35,feet = 94;
    rab = feet/2 - head;//47对脚,多出来的是属于兔子剩下的12对脚
    chick = head - rab;
    cout<<chick<<" "<<rab;
    return 0;
}

三、百钱买百鸡问题

【题目描述】公鸡 5 文钱一只,母鸡 3 文钱一只,小鸡 3 只一文钱,用 100 文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足 100 文钱。

【输出】 4  18  78

                8  11  81

               12  4  84

----------------------------------------------------------------------------------------------------

已知 5 钱一只鸡翁, 3 钱一只鸡母, 1/3 钱一只鸡雏。我们先要确定怎么去循环才能让最后的结果为 ? 只鸡翁和 ? 只鸡母以及多少只 ? 鸡雏。

#include<iostream>
using namespace std;
//鸡翁、鸡母、鸡雏
//5       3    1/3
//20      33    ?  
int main()
{
    int i,j,k;
    for(i = 1; i < 20; i++)
    {
        for(j = 1; j <= 33; j++)
        {
            k = 100 - i -j;
            if(i * 5 + j * 3 + k/3 == 100 && k % 3 == 0)
                cout<<i<<" "<<j<<" "<<k<<endl;
        }
    }
    return 0;
}

所以程序是先把鸡翁做外循环,再让鸡母做内循环。内层循环中放一个等式算出鸡雏的数量

k = 100  - i - j

然后继续在内层循环做判断,关于鸡翁鸡母鸡雏的数量加起来不超过 100 钱。

有: i * 5 +  j * 3 + k/3 == 100 && k%3 == 0)

满足以上条件,就能输出i j  k的值了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值