洛谷P2698 [USACO12MAR] Flowerpot S(二分、单调队列)

通过二分查找和单调队列分析水滴高度,求解在给定时间差下花盆宽度的最小值,实现接水问题的编程解决方案。
摘要由CSDN通过智能技术生成

题目描述

老板需要你帮忙浇花。给出 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)
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重生之我是oi高手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值