HDU 6119 小小粉丝度度熊(Two pointers)

 

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6119

 

【题目大意】

  给出一些签到区间和一些补签卡,问可以创造的最长连续签到区间

 

【题解】

  如果我们知道选定的最左和最右的签到区间,
  我们就可以计算出需要补多少的补签卡,如果数量小于等于给定数量,
  那么这个左右可以用来更新答案。所以尺取法就显而易见了。

 

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100010;
struct data{int l,r;}p[N];
int l[N],r[N],cnt;
bool cmp(data a,data b){
    if(a.l==b.l)return a.r<b.r;
    return a.l<b.l;
}
int n,m; 
int main(){
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++)scanf("%d%d",&p[i].l,&p[i].r);
        sort(p+1,p+n+1,cmp); cnt=1;
        l[cnt]=p[1].l,r[cnt]=p[1].r;
        for(int i=2;i<=n;i++){
            if(p[i].l-1>r[cnt]){l[++cnt]=p[i].l;r[cnt]=p[i].r;}
            r[cnt]=max(r[cnt],p[i].r);
        }
        int ans=r[1]-l[1]+1+m,gap=0,lft=1;
        for(int rt=2;rt<=cnt;rt++){
            gap+=l[rt]-1-r[rt-1];
            while(gap>m){lft++;gap-=l[lft]-1-r[lft-1];}
            ans=max(ans,r[rt]-l[lft]+1+m-gap);
        }printf("%d\n",ans);
    }return 0;
}
posted @ 2017-08-14 14:12  forever97  阅读(430)  评论(0编辑  收藏  举报