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; }
愿你出走半生,归来仍是少年