正题
链接
https://www.luogu.org/record/show?rid=7934370
大意
有n滴水,给出坐标,水每一个时间单位会往下掉一格,花盆可以随意摆放,要求在宽度最小的情况下接住的第一滴水和最后一滴水时间差超过D
解题思路
横坐标排序,枚举左边,然后维护移动窗口,之后递增右边直到时间差大于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);
}