题目描述
老板需要你帮忙浇花。给出 N 滴水的坐标,y 表示水滴的高度,x 表示它下落到 x 轴的位置。每滴水以每秒 1 个单位长度的速度下落。你需要把花盆放在 x 轴上的某个位置,使得从被花盆接着的第 1 滴水开始,到被花盆接着的最后 1 滴水结束,之间的时间差至少为 D。
我们认为,只要水滴落到 x 轴上,与花盆的边沿对齐,就认为被接住。给出 N 滴水的坐标和 D 的大小,请算出最小的花盆的宽度 W。
输入格式
第一行 2 个整数 N 和 D。
接下来 N 行每行 2 个整数,表示水滴的坐标 (x,y)。
输出格式
仅一行 1 个整数,表示最小的花盆的宽度。如果无法构造出足够宽的花盆,使得在 D 单位的时间接住满足要求的水滴,则输出 −1。
解题思路
可以用二分确定花盆宽度,再使用单调队列求出该宽度范围内水滴高度最大值和最小值,若差大于D,则该宽度可以满足条件。
代码
n, d = map(int, input().split())
a = []
maxx, minx = 0, 10e6
for i in range(n):
x, y = map(int, input().split())
maxx = max(maxx, x)
minx = min(minx, x)
a.append([x, y])
a.sort(key=lambda x:x[0])
l, r = 1, maxx - minx + 1
ans = -1
while l <= r:
m = (l + r) // 2
h1, h2, r1, r2 = 0, 0, -1, -1
s1, s2 = [0 for _ in range(n)], [0 for _ in range(n)]
flag = False
for i in range(n):
while h1 <= r1 and a[s1[r1]][1] > a[i][1]:
r1 -= 1
r1 += 1
s1[r1] = i
while h2 <= r2 and a[s2[r2]][1] < a[i][1]:
r2 -= 1
r2 += 1
s2[r2] = i
while a[s1[h1]][0] + m < a[i][0]:
h1 += 1
while a[s2[h2]][0] + m < a[i][0]:
h2 += 1
if a[s2[h2]][1] - a[s1[h1]][1] >= d:
ans = m
r = m - 1
flag = True
break
if flag == False:
l = m + 1
print(ans)