P2698 [USACO12MAR] Flowerpot S
文章目录
- P2698 [USACO12MAR] Flowerpot S
- 题目描述
- 输入格式
- 输出格式
- 样例 #1
- 样例输入 #1
- 样例输出 #1
- 提示
- 思路分析
- code
[P2698 USACO12MAR] Flowerpot S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
Farmer John has been having trouble making his plants grow, and needs your help to water them properly. You are given the locations of N raindrops (1 <= N <= 100,000) in the 2D plane, where y represents vertical height of the drop, and x represents its location over a 1D number line:
Each drop falls downward (towards the x axis) at a rate of 1 unit per second. You would like to place Farmer John’s flowerpot of width W somewhere along the x axis so that the difference in time between the first raindrop to hit the flowerpot and the last raindrop to hit the flowerpot is at least some amount D (so that the flowers in the pot receive plenty of water). A drop of water that lands just on the edge of the flowerpot counts as hitting the flowerpot.
Given the value of D and the locations of the N raindrops, please compute the minimum possible value of W.
老板需要你帮忙浇花。给出 N N N 滴水的坐标, y y y 表示水滴的高度, x x x 表示它下落到 x x x 轴的位置。
每滴水以每秒 1 1 1 个单位长度的速度下落。你需要把花盆放在 x x x 轴上的某个位置,使得从被花盆接着的第 1 1 1 滴水开始,到被花盆接着的最后 1 1 1 滴水结束,之间的时间差至少为 D D D。
我们认为,只要水滴落到 x x x 轴上,与花盆的边沿对齐,就认为被接住。给出 N N N 滴水的坐标和 D D D 的大小,请算出最小的花盆的宽度 W W W。
输入格式
第一行 2 2 2 个整数 N N N 和 D D D。
接下来 N N N 行每行 2 2 2 个整数,表示水滴的坐标 ( x , y ) (x,y) (x,y)。
输出格式
仅一行 1 1 1 个整数,表示最小的花盆的宽度。如果无法构造出足够宽的花盆,使得在 D D D 单位的时间接住满足要求的水滴,则输出 − 1 -1 −1。
样例 #1
样例输入 #1
4 5
6 3
2 4
4 10
12 15
样例输出 #1
2
提示
有 4 4 4 滴水, ( 6 , 3 ) (6,3) (6,3) , ( 2 , 4 ) (2,4) (2,4) , ( 4 , 10 ) (4,10) (4,10) , ( 12 , 15 ) (12,15) (12,15) 。水滴必须用至少 5 5 5 秒时间落入花盆。花盆的宽度为 2 2 2 是必须且足够的。把花盆放在 x = 4 … 6 x=4\dots6 x=4…6 的位置,它可以接到 1 1 1 和 3 3 3 水滴, 之间的时间差为 10 − 3 = 7 10-3=7 10−3=7 满足条件。
【数据范围】
40 % 40\% 40% 的数据: 1 ≤ N ≤ 1000 1 \le N \le 1000 1≤N≤1000 , 1 ≤ D ≤ 2000 1 \le D \le 2000 1≤D≤2000 。
100 % 100\% 100% 的数据: 1 ≤ N ≤ 1 0 5 1 \le N \le 10 ^ 5 1≤N≤105 , 1 ≤ D ≤ 1 0 6 1 \le D \le 10 ^ 6 1≤D≤106 , 0 ≤ x , y ≤ 1 0 6 0\le x,y\le10^6 0≤x,y≤106 。
思路分析
枚举左端点
用两个单调队列位数区间最大值和最小值
然后看一下是否满足条件,求一下最小代价就好了
code
#include <bits/stdc++.h>
#define fu(x , y , z) for(int x = y ; x <= z ; x ++)
using namespace std;
const int N = 1e5 + 5 , inf = 1e9 + 5;
int n , d , ans = inf;
struct node {
int x , y;
} t[N];
bool cmp (node x , node y) { return x.x < y.x; }
list<int> s1;
list<int> s2;
int main () {
scanf ("%d%d" , &n , &d);
fu (i , 1 , n)
scanf ("%d%d" , &t[i].x , &t[i].y);
sort (t + 1 , t + n + 1 , cmp);
int r = 0;
fu (l , 1 , n) {
while (!s1.empty() && s1.front() < l) s1.pop_front();
while (!s2.empty() && s2.front() < l) s2.pop_front();
if (s1.empty()) s1.push_back(l) , s2.push_back(l);
while (!s1.empty() && !s2.empty() && t[s1.front()].y - t[s2.front()].y < d && r < n) {
r ++;
while (!s1.empty() && t[s1.back()].y < t[r].y) s1.pop_back();
s1.push_back(r);
while (!s2.empty() && t[s2.back()].y > t[r].y) s2.pop_back();
s2.push_back(r);
}
if (!s1.empty() && !s2.empty() && t[s1.front()].y - t[s2.front()].y >= d)
ans = min (ans , t[r].x - t[l].x);
}
if (ans == inf) printf ("-1");
else printf ("%d" , ans);
}