P2698-花盆Flowerpot【单调队列】

正题

链接
https://www.luogu.org/record/show?rid=7934370


大意

有n滴水,给出坐标,水每一个时间单位会往下掉一格,花盆可以随意摆放,要求在宽度最小的情况下接住的第一滴水和最后一滴水时间差超过D
From Luogu


解题思路

横坐标排序,枚举左边,然后维护移动窗口,之后递增右边直到时间差大于D,然后记录取最小值。


代码

#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
    int x,t;
}a[100001];
int h1,t1,h2,t2,q[100001],q2[100001];
int n,D,ans,r;
bool cmp(node x,node y)//排序
{
    return x.x<y.x;
}
int main()
{
    scanf("%d%d",&n,&D);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].t);
    }
    sort(a,a+1+n,cmp);
    h1=1;t1=0;ans=2147483647;
    h2=1;t2=0;r=0;
    for (int l=1;l<=n;l++)
    {
        while (h1<=t1&&q[h1]<l) h1++;
        while (h2<=t2&&q2[h2]<l) h2++;//维护移动窗口
        while (a[q[h1]].t-a[q2[h2]].t<D&&r<n)
        {
            r++;//寻找右端点
            while (h1<=t1&&a[r].t>a[q[t1]].t) t1--;
            while (h2<=t2&&a[r].t<a[q2[t2]].t) t2--;
            //维护单调队列
            q[++t1]=q2[++t2]=r;//加入队列
        }
        if (a[q[h1]].t-a[q2[h2]].t>=D)
          ans=min(ans,a[r].x-a[l].x);//更新最小值
    }
    if (ans==2147483647) printf("-1");
    else printf("%d",ans);
}

转载于:https://www.cnblogs.com/sslwyc/p/9218507.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值