CodeForces754D【贪心】

来源:互联网 发布:深圳淘宝模特拍摄 编辑:程序博客网 时间:2024/05/22 03:37
题意:
有n个区间,每个区间覆盖区间里一段数,求最大连续区间长度被覆盖k次,并输出选取的区间。
思路:
贪心;
感觉一开始肯定是要把区间按left从小到大排序的。
然后肯定是连续k个区间能够达到的重叠最长?
因为left已经足够小了?
3 2
1 100
30 70
31 78
这个案例就说明这样贪心还不是准确的。
其实不管k多大,只有一个left,一个right,left大,right小这样是最差的,也是最长的最小。
现在就是进来的时候,left就是很大啊!
然后只要考虑right是不是又特别小。ok!!!!就是这样啊!!
用优先队列维护right,队列头的right最小就好了

//#include <bits/stdc++.h>#include<iostream>#include<cstdio>#include<queue>#include<math.h>#include<string.h>#include<algorithm>using namespace std;typedef long long LL;typedef pair<int,int> PII;const int N=3e5+10;struct asd{    int left,right,id;    friend bool operator< (asd n1,asd n2)    {        return n1.right>n2.right;    }};bool cmp(asd n1,asd n2){    if(n1.left==n2.left) return n1.right<n2.right;    return n1.left<n2.left;}asd now[N];priority_queue<asd>q;int main(){    int n,k,s,t;    scanf("%d%d",&n,&k);    for(int i=0;i<n;i++)    {        scanf("%d%d",&s,&t);        now[i].left=s;        now[i].right=t;        now[i].id=i+1;    }    int ans,rightmin,leftmax;    sort(now,now+n,cmp);    ans=0;     for(int i=0;i<n;i++)    {        q.push(now[i]);        if(q.size()>k)            q.pop();        if(q.size()==k)        {            leftmax=now[i].left;            if((q.top().right-leftmax+1)>ans)            {                ans=q.top().right-leftmax+1;                rightmin=q.top().right;            }        }    }    printf("%d\n",ans);    if(ans==0)        for(int i=1;i<=k;i++)            printf("%d ",i);    else        for(int i=0;i<n;i++)            if(k&&now[i].left<=leftmax && now[i].right>=rightmin){                     printf("%d ",now[i].id);                    k--;        }     return 0;}

0 0