hdu6119 尺取 双指针

版权声明:编写不易,转载请注明出处,谢谢。 https://blog.csdn.net/WilliamSun0122/article/details/77165126

中文题就不说题意了。

题解
题目已经说了区间会存在交叉,所以我们先把区间排序后把交叉的区间合并起来。然后用一个数组存放相邻两个区间的差距,之后双指针尺取即可。最后算一下如果只有一个区间时的天数。
代码还是很好懂的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;

ll n,m;
ll dis[maxn];
struct Node{
    ll l,r;
}tmp[maxn],node[maxn];

bool cmp(Node a,Node b)
{
    if(a.l==b.l) return a.r<b.r;
    else return a.l<b.l;
}


int main()
{
    while(~scanf("%lld%lld",&n,&m))
    {
        for(int i=0;i<n;i++) scanf("%lld%lld",&tmp[i].l,&tmp[i].r);
        sort(tmp,tmp+n,cmp);
        int num=1;
        node[num] = tmp[0];
        for(int i=1;i<n;i++)
        {
            if(tmp[i].l<=node[num].r+1) node[num].r = max(node[num].r,tmp[i].r);
            else node[++num] = tmp[i];
        }
        for(int i=1;i<num;i++) dis[i] = node[i+1].l-node[i].r-1;
        ll res=0,ans=-1;
        int cnt=1;
        for(int i=1;i<num;i++)
        {
            res += dis[i];
            while(res>m) res -= dis[cnt++];
            ans = max(ans,node[i+1].r-node[cnt].l+1+m-res);
        }
        ans = max(ans,node[1].r-node[1].l+1+m);
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WilliamSun0122/article/details/77165126