每日算法-枚举:程序设计实践1

简介:UPC程序设计实践课程精选算法题讲解附代码

【题目编号】

       枚举 6

【题目大意】

    输入一个整数n ,任意3个整数0 <= a1, a2, a3 <= n, 且a1 + a2是2的倍数、a2 + a3是3的倍数、 a1 + a2 + a3是5的倍数,输出三者和的最大值。

【解题思路】

    因为输入的n已确定<=100,拆分过程随意,无法通过计算规律得出解题公式,只能一一枚举;一般通过三个for循环,时间复杂度为O(n^3)也是可以接受的,最后再通过求模判断得到结果。但是,为使时间复杂度降低,可以在第二层和第三次循环之间添加一个2的倍数的判断,把第三层进行的循环次数减少一半,而且在最后判断的时候可以提前减少一个且的判断条件,从而问题得解。

【参考代码】 

#include<iostream>
using namespace std;
int main()
{
    int a1,a2,a3,n;
    int x=0;
    cin>>n;
    for(a1=0; a1<=n; ++a1)
    {
        for(a2=0; a2<=n; ++a2)
        {
            if((a1+a2)%2==0)
            {
                for(a3=0; a3<=n; ++a3)
                {
                    if((a2+a3)%3==0&&(a1+a2+a3)%5==0&&(a1+a2+a3)>x)
                        {
                            x=a1+a2+a3;
                        }
                } 
            }

        }
    }
    cout<<x<<endl;
    return 0;
}

题目编号

       枚举 7

题目大意

          输入一个不大于10000的正整数S,为两个质数的和。输出一个整数,为两个质数的最大乘积,且数据保证有解。

【解题思路】

     这是一个质数求解问题,通过前面的学习已经掌握了质数判别法,本题可以将输入的S进行拆开,然后再判断拆分出来的两个数是否都是质数,如果是则符合要求第一步;第二步是输出最大乘机;这里为解决再次使用循环耗时耗空间的问题,可以在拆分的时候从中间向两边展开,因为和一定时,越靠近的两个数起乘积越大,问题得解。

参考代码

#include <iostream>

#include <cmath>

using namespace std;

int pr(int x)

{

    for(int i=2;i<=sqrt(x);i++)

    {

        if(x%i==0)

        {

            return 0;

            break;

        }

    }

    return 1;

}

int main()

{

    int s;

    cin>>s;

    for(int j=s/2;j>=2;j--)

    {

        if(pr(j)&&pr(s-j))

        {

            cout<<j*(s-j)<<endl;

            break;

        }

    }

    return 0;

}

题目编号

       枚举 8

题目大意

给定正整数a,b,c为不定方程 ax+by=c 的值,求出关于未知数x和y的所有非负整数解的组数,而且每个数都<=1000。

解题思路

       直接使用暴力法就可以解决,两层循环最后把方程式最为判断条件,得到的次数即为解的组数。

参考代码

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

    int a,b,c,n=0;

    cin>>a >>b >>c;

    for(int i=0;i<=c;i++)

    {

        for(int j=0;j<=c;j++)

        {

            if(a*i+b*j==c)

            {

                n++;

            }

        }

    }

    cout<<n<<endl;

    return 0;

}

题目编号

     枚举 9

题目大意

        给出6个整数作为不同单位砝码的个数,求使用现有的砝码可以称出多少种不同的重量,而且总重量<=1000,输出可以称出的不同重量的个数。

解题思路

    对同一种的砝码可以过个数增加,不同的可以通过种类进行搭配,进而每个砝码都是自变量;通过枚举的暴力法,进行6重循环,对每次搭配的个数不急于立马输出,而且通过数组里每个存储的量必须<=1000才能满足条件。

参考代码

#include<iostream>

using namespace std;

int flag[1005] = { 0 };

int main()

{

       int a1, a2, a3, a4, a5, a6;

       cin >> a1 >> a2 >> a3 >> a4 >> a5 >> a6;

       for (int i1 = 0; i1 <= a1; i1++)

       {

              for (int i2 = 0; i2 <= a2; i2++)

              {

                     for (int i3 = 0; i3 <= a3; i3++)

                     {

                            for (int i4 = 0; i4<= a4; i4++)

                            {

                                   for (int i5 = 0; i5 <= a5; i5++)

                                   {

                                          for (int i6 = 0; i6 <= a6; i6++)

                                          {

                                                 int sum = i1 + i2 * 2 + i3 * 3 + i4 * 5 + i5 * 10 + i6 * 20;

                                                 flag[sum] = 1;

                                          }

                                   }

                            }

                     }

              }

       }

       int count = 0;

       for (int i = 1; i <= 1000;i++)

       {

              if (flag[i])

              {

                     count++;

              }

       }

       cout << "Total="<<count << endl;

       return 0;

}

写在最后

以上代码仅供同学们参考,切勿复制粘贴、1草草了事,东西是给自己学的、对自己负责;时间关系没有给大家做代码注释,希望同学们上课时候认真听讲、做到举一反三。

如有雷同纯属巧合、若有侵权请及时联系删文

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云边牧风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值