小小粉丝度度熊
Posted wang者归来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小小粉丝度度熊相关的知识,希望对你有一定的参考价值。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6119
Problem Description 度度熊喜欢着喵哈哈村的大明星——星星小姐。 为什么度度熊会喜欢星星小姐呢? 首先星星小姐笑起来非常动人,其次星星小姐唱歌也非常好听。 但这都不是最重要的,最重要的是,星星小姐拍的一手好代码! 于是度度熊关注了星星小姐的贴吧。 一开始度度熊决定每天都在星星小姐的贴吧里面签到。 但是度度熊是一个非常健忘的孩子,总有那么几天,度度熊忘记签到,于是就断掉了他的连续签到。 不过度度熊并不是非常悲伤,因为他有m张补签卡,每一张补签卡可以使得某一忘签到的天,变成签到的状态。 那么问题来了,在使用最多m张补签卡的情况下,度度熊最多连续签到多少天呢? Input 本题包含若干组测试数据。 第一行两个整数n,m,表示有n个区间,这n个区间内的天数,度度熊都签到了;m表示m张补签卡。 接下来n行,每行两个整数(l[i],r[i]),表示度度熊从第l[i]天到第r[i]天,都进行了签到操作。 数据范围: 1<=n<=100000 0<=m<=1000000000 0<=l[i]<=r[i]<=1000000000 注意,区间可能存在交叉的情况。 Output 输出度度熊最多连续签到多少天。 Sample Input 2 1 1 1 3 3 1 2 1 1 Sample Output 3 3 Hint 样例一:度度熊补签第2天,然后第1天、第二天和第三天都进行了签到操作。 样例二:度度熊补签第2天和第3天。
就是一道模拟题,不知被撒旦诅咒了还是咋的,写了好几种代码都没对,还耗费了一下午(倒是练习了一题多解,也提升了打代码的能力)
思路一:维护一个先进先出的队列,每当有空隙时,就让m减小,当M不能填补空洞时,出队M加前面的空洞长。对每一个队列的长取max。
思路二:把重叠区间合并,生成一个新数组gap[]表示 每个空区间的长度。算是一种简化吧。
#include<iostream> #include<cstdio> #include<string> #include<cmath> #include<vector> #include<map> #include<set> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define LL long long #define M 100005 int gap[M]; struct node{ LL l,r; }a[M],b[M]; LL n,m; bool cmp(node u,node v) { if(u.l==v.l) return u.r>v.r; return u.l<v.l; } int main() { while(scanf("%lld%lld",&n,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i].l,&a[i].r); sort(a+1,a+1+n,cmp); int tot=1; b[tot]=a[1]; for(int i=2;i<=n;i++) { if(a[i].l<=b[tot].r+1) b[tot].r=max(b[tot].r,a[i].r); else b[++tot]=a[i]; } for(int i=1;i<=tot;i++) gap[i]=b[i+1].l-b[i].r-1; LL used=0,l=1; LL ans=b[1].r-b[1].l+1+m; for(int i=1;i<tot;i++) { used+=gap[i]; while(used>m) used-=gap[l++]; ans=max(ans,b[i+1].r-b[l].l+1+m-used); } printf("%lld\n",ans); } return 0; }
以上是关于小小粉丝度度熊的主要内容,如果未能解决你的问题,请参考以下文章
2017"百度之星"程序设计大赛 - 初赛(B)小小粉丝度度熊