1. 程式人生 > 實用技巧 >[補題記錄] ccpc-2016 2017-finals problem E - Problem Buyer Gym - 101206E

[補題記錄] ccpc-2016 2017-finals problem E - Problem Buyer Gym - 101206E

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\n",num);
            if(num<=0) flag=1;
            ans=max(ans,n-num+1);
            if(!qu.empty()) qu.pop();
        }
        if(flag) printf("Case #%d: IMPOSSIBLE!\n",k);
        else printf("Case #%d: %d\n",k,ans);
    }
    return 0;
}