竞赛笔记(3)

题目

这是一道典型的贪心题目,用最少的反导系统拦截最多的导弹。先使用第一套反导系统,从a数组一路读取下去,遇到比它大的就增加一套反导系统,并将后续的导弹读入到两套反导系统中的其中一个,因为此时已经有两套反导系统,一路循环继续读取下去,如果遇到导弹高度两套反导系统都无法拦截的,那就再加一套,如此一直持续下去,最后输出结果即可。

#include <iostream>
using namespace std;
typedef long long ll;//给longlong起一个叫ll的外号,方便后续输入;
ll a[1000000];
ll b[1000000];
int main()
{
    ll num,c;//num代表导弹的数量,c代表反导系统的数目
    ll d=1;//将变量d作为标志,如果d=1,那么说明已有系统可以拦截,否则便需要增加一套
    while(cin>>num)//划重点!!!我在这里被坑了一个多小时AC不了就是因为这个,虽然题目没有说明需要多次使用,但是如果你的程序只能使用一次的话就算答案是对的最后也会WA,所以建议以后做题目的时候都设置可以多次使用
    {
    c=1;//因为可以多次使用,所以每次程序开始执行的时候都需要先将上一次算出来的导弹数量重置回1
    for(ll i=1;i<=num;i++)
    {
        cin>>a[i];
        b[i]=a[i];//将a数组的数据复制到b中去
    }
    for(ll i=2;i<=num;i++)
    {
        d=0;//先自动转换为0,使其初始状态表示为需要多一套反导系统
        for(ll j=1;j<=c;j++)
        {
           if(a[i]<=b[j])//如果后面一个的导弹高度比前一个小的话,那就将d赋值回1,并使用break直接跳出循环不让j自加
           {
               d=1;
               b[j]=a[i];//这个和下面的b[c]=a[i]的逻辑会比较抽象,下面我画了一张图,希望能看懂
               break;
           }
        }
        if(d==0)//如果后面一个的导弹高度比前一个大的话,那么d值不变,此时d=0
        {
            c++;//反导系统加多一套
            b[c]=a[i];
        }
    }
    cout<<c<<endl;
    }
    return 0;
}

关于“ b[j]=a[i]”和“b[c]=a[i]”的解释图如下:(使用题目样例)

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页