[补题记录] 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;
}