P2698 [USACO12MAR] Flowerpot S

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:

P2698 [USACO12MAR] Flowerpot S_第1张图片

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=46 的位置,它可以接到 1 1 1 3 3 3 水滴, 之间的时间差为 10 − 3 = 7 10-3=7 103=7 满足条件。

【数据范围】

40 % 40\% 40% 的数据: 1 ≤ N ≤ 1000 1 \le N \le 1000 1N1000 1 ≤ D ≤ 2000 1 \le D \le 2000 1D2000

100 % 100\% 100% 的数据: 1 ≤ N ≤ 1 0 5 1 \le N \le 10 ^ 5 1N105 1 ≤ D ≤ 1 0 6 1 \le D \le 10 ^ 6 1D106 0 ≤ x , y ≤ 1 0 6 0\le x,y\le10^6 0x,y106

思路分析

枚举左端点

用两个单调队列位数区间最大值和最小值

然后看一下是否满足条件,求一下最小代价就好了

code

#include 
#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);
}

你可能感兴趣的:(USACO,题解,数据结构,算法,数据结构,学习,笔记)