[补题记录] ccpc-2016 2017-finals problem E

E - Problem Buyer Gym - 101206E

题意:

有n道题(每题只能用一次),分别给定难度区间,需要m道题,每道题都有一个难度,求最小区间数k
满足所有m个难度都能包含在k个难度区间中,若无法找到k则输出impossible

题解:

别把问题想复杂了!贪!心!就!行!!!

咋贪?

对于每个题来讲,如果有num个区间不满足它,那num+1个区间里就一定有一个满足它

所以对每个题的num+1,取个max

还有要注意的是 每个题只能用一次啊(我一开始就没看懂) 所以如果要想我那样子遍历的话 pos要放外面 然后要先把满足条件的吃进来,再把不满足条件的吐出去

每次找到一个区间就把最前面的pop掉(贪心嘛,把对下一个影响最小的弹掉)

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int l,r;
}x[100019];
int a[100019];
int cmp(node a,node b)
{
    if(a.l==b.l) return a.r<b.r;
    return a.l<b.l;
}
priority_queue<int,vector<int>,greater<int> >qu;
int main()
{
    int t,n,m;
    scanf("%d",&t);
    for(int k=1; k<=t; k++)
    {
        while(!qu.empty()) qu.pop();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i].l,&x[i].r);
        }
        for(int i=1;i<=m;i++) 
        {
            scanf("%d",&a[i]);
        }
        sort(a+1,a+1+m);
        sort(x+1,x+1+n,cmp);
        int ans=0,flag=0;
        int pos=1;
        for(int i=1;i<=m;i++)
        {
            while(x[pos].l<=a[i])
            {
                if(pos>n) break;
                qu.push(x[pos].r);
                pos++;
            }
            while(!qu.empty())
            {
                int now=qu.top();
                if(now>=a[i]) break;
                qu.pop();
            }
            int num=qu.size();
        //    printf("num=%d
",num);
            if(num<=0) flag=1;
            ans=max(ans,n-num+1);
            if(!qu.empty()) qu.pop();
        }
        if(flag) printf("Case #%d: IMPOSSIBLE!
",k);
        else printf("Case #%d: %d
",k,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/YangKun-/p/13493427.html