老板需要你帮忙浇花。给出N滴水的坐标,y表示水滴的高度,x表示它下落到x轴的位置。
每滴水以每秒1个单位长度的速度下落。你需要把花盆放在x轴上的某个位置,使得从被花盆接着的第1滴水开始,到被花盆接着的最后1滴水结束,之间的时间差至少为D。
我们认为,只要水滴落到x轴上,与花盆的边沿对齐,就认为被接住。给出N滴水的坐标和D的大小,请算出最小的花盆的宽度W。
输入格式
第一行2个整数 N 和 D。
第2.. N+1行每行2个整数,表示水滴的坐标(x,y)。
输出格式
仅一行1个整数,表示最小的花盆的宽度。如果无法构造出足够宽的花盆,使得在D单位的时间接住满足要求的水滴,则输出-1。
输入输出样例
输入 #1复制
4 5 6 3 2 4 4 10 12 15
输出 #1复制
2
说明/提示
【样例解释】
有4滴水, (6,3), (2,4), (4,10), (12,15).水滴必须用至少5秒时间落入花盆。花盆的宽度为2是必须且足够的。把花盆放在x=4..6的位置,它可以接到1和3水滴, 之间的时间差为10-3 = 7满足条件。
【数据范围】
40%的数据:1 ≤ N ≤ 1000,1 ≤ D ≤ 2000;
100%的数据:1 ≤ N ≤ 100000,1 ≤ D ≤ 1000000,0≤x,y≤10^6。
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,d,h1,h2,t1,t2,ans=1e9;
int q1[N],q2[N];
struct node
{
int x, y;
bool operator<(const node &y) const { return x < y.x; }
} a[N];
int main()
{
int l = 1, i, r;
h1 = h2 = 1;
cin>>n>>d;
for(i=1; i<=n; ++i) cin>>a[i].x>>a[i].y;
sort(a+1,a+n+1);
for(l=1,r=0; l<=n; ++l)
{
while(h1<=t1&&q1[h1]<l) ++h1; // 维护滑动窗口
while(h2<=t2&&q2[h2]<l) ++h2;
while(a[q1[h1]].y-a[q2[h2]].y < d && r < n)
{
++r;
while(a[q1[t1]].y < a[r].y && h1<=t1)
{
--t1;
}
q1[++t1]=r; //维护单调队列
while(a[q2[t2]].y > a[r].y && h2<=t2)
{
--t2;
}
q2[++t2]=r;
}
if(a[q1[h1]].y-a[q2[h2]].y >= d) ans = min(ans,a[r].x-a[l].x);
}
printf("%d",ans>=1e9?-1:ans);
return 0;
}