NC24325 [USACO 2012 Mar S]Flowerpot

题目

题目描述

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.

输入描述

  • Line 1: Two space-separated integers, N and D. (1 <= D <=

    1,000,000)

  • Lines 2..1+N: Line i+1 contains the space-separated (x,y)

    coordinates of raindrop i, each value in the range

    0...1,000,000.

输出描述

  • Line 1: A single integer, giving the minimum possible width of the

    flowerpot. Output -1 if it is not possible to build a

    flowerpot wide enough to capture rain for at least D units of

    time.

示例1

输入

4 5
6 3
2 4
4 10
12 15

输出

2

说明

INPUT DETAILS:

There are 4 raindrops, at (6,3), (2,4), (4,10), and (12,15). Rain must

fall on the flowerpot for at least 5 units of time.

OUTPUT DETAILS:

A flowerpot of width 2 is necessary and sufficient, since if we place it

from x=4..6, then it captures raindrops #1 and #3, for a total rain

duration of 10-3 = 7.

题解

思路

方法一

知识点:单调队列,二分。

求可行答案的最小值,第一个想到的就是二分答案,检验答案是否可行。

验证一个区间是否可行,首先要知道一个区间最大最小值,但是这个区间是可变的,考虑用单调队列维护一个定长移动区间最大最小值。

细节上要注意,由于区间长度是非线性变化的,所以用while和两个端点指针来保证每一个区间是 \(<=mid\) 最大区间。并且队头弹出操作,队尾加入新元素操作,都是需要一个while维持的,因为不保证合法区间需要操作几个点。初始化时,要在 \(<=mid\) 最大区间之前保留一个点,方便之后遍历是从第一个区间开始的。因为检验可行性就行,所以遇到一个可行就可以跳出了。

时间复杂度 \(O(n \log x_{max})\)

空间复杂度 \(O(n)\)

方法二

知识点:尺取法,单调队列。

首先,如果右端点找到一个合法区间,改变左端点时,不需要将右端点重置到左端点处,因为首末雨滴时差随区间变大是只增不减的,所以右端点一直往右即可,符合尺取法。

维护变区间最大最小值用单调队列即可,细节如上。

注意到,由于内循环需要一开始就检测是否已经合法,而不是加入后检测,因为为了固定右端点,改变左端点得到的合法区间都取到。因此为了防止空队列被访问,一开始加入一个点使得队列持续非空即可。

每次和答案取最小值时,要在前面加一个判断是否合法,因为可能导致内循环跳出的不是区间合法而是右端点到头了。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

方法一

#include <bits/stdc++.h>

using namespace std;

struct Point {
int x, y;
}a[1000007];
int n, d; bool check(int mid) {
deque<int> dq1, dq2;
int l = 0, r = 0;
while (r < n - 1 && a[r + 1].x - a[0].x <= mid) {///单调递增/递减队列初始化,以获得所有长为mid的区间的最小值/最大值
while (!dq1.empty() && a[dq1.back()].y >= a[r].y) dq1.pop_back();
dq1.push_back(r);
while (!dq2.empty() && a[dq2.back()].y <= a[r].y) dq2.pop_back();
dq2.push_back(r);
r++;
}
int cnt = 0;
while (r < n) {
while (a[r].x - a[l].x > mid) l++;
while (!dq1.empty() && dq1.front() < l) dq1.pop_front();
while (!dq2.empty() && dq2.front() < l) dq2.pop_front();
while (r < n && a[r].x - a[l].x <= mid) {
while (!dq1.empty() && a[dq1.back()].y >= a[r].y) dq1.pop_back();
dq1.push_back(r);
while (!dq2.empty() && a[dq2.back()].y <= a[r].y) dq2.pop_back();
dq2.push_back(r);
r++;
}
if (a[dq2.front()].y - a[dq1.front()].y >= d) return true;
}
return false;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> d;
for (int i = 0;i < n;i++) cin >> a[i].x >> a[i].y;
sort(a, a + n, [&](Point a, Point b) {return a.x == b.x ? a.y < b.y : a.x < b.x;}); int l = 1, r = a[n - 1].x;
while (l <= r) {
int mid = l + r >> 1;
if (check(mid)) r = mid - 1;
else l = mid + 1;
}
cout << (l > a[n - 1].x ? -1 : l) << '\n';
return 0;
}

方法二

///注意边界,可以通过初始化减少if语句长度
#include <bits/stdc++.h> using namespace std; struct Point {
int x, y;
}a[1000007]; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, d;
cin >> n >> d;
for (int i = 0;i < n;i++) cin >> a[i].x >> a[i].y;
sort(a, a + n, [&](Point a, Point b) {return a.x == b.x ? a.y < b.y : a.x < b.x;}); deque<int> dq1, dq2;
dq1.push_back(0);
dq2.push_back(0);
int l = 0, r = 1;
int ans = ~(1 << 31);
while (l < n) {
while (r < n) {
if (a[dq2.front()].y - a[dq1.front()].y >= d) break;
while (!dq1.empty() && a[dq1.back()].y >= a[r].y) dq1.pop_back();
dq1.push_back(r);
while (!dq2.empty() && a[dq2.back()].y <= a[r].y) dq2.pop_back();
dq2.push_back(r);
r++;
}
if (a[dq2.front()].y - a[dq1.front()].y >= d) ans = min(ans, a[r - 1].x - a[l].x);
if (l == dq1.front()) dq1.pop_front();
if (l == dq2.front()) dq2.pop_front();
l++;
}
cout << (ans > a[n - 1].x ? -1 : ans) << '\n';
return 0;
}

NC24325 [USACO 2012 Mar S]Flowerpot的更多相关文章

  1. [USACO 2012 Mar Silver] Landscaping【Edit Distance】

    传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=126 好题啊好题,一开始就输给了这道题的想法! 先把原始状态以及目标状态换 ...

  2. [USACO 2012 Mar Gold] Large Banner

    传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢 ...

  3. USACO翻译:USACO 2012 FEB Silver三题

    USACO 2012 FEB SILVER 一.题目概览 中文题目名称 矩形草地 奶牛IDs 搬家 英文题目名称 planting cowids relocate 可执行文件名 planting co ...

  4. USACO翻译:USACO 2012 JAN三题(2)

    USACO 2012 JAN(题目二) 一.题目概览 中文题目名称 叠干草 分干草 奶牛联盟 英文题目名称 stacking baleshare cowrun 可执行文件名 stacking bale ...

  5. USACO翻译:USACO 2012 JAN三题(1)

    USACO 2012 JAN(题目一) 一.题目概览 中文题目名称 礼物 配送路线 游戏组合技 英文题目名称 gifts delivery combos 可执行文件名 gifts delivery c ...

  6. 【USACO 2012 Open】Running Laps(树状数组)

    53 奶牛赛跑 约翰有 N 头奶牛,他为这些奶牛准备了一个周长为 C 的环形跑牛场.所有奶牛从起点同时起跑,奶牛在比赛中总是以匀速前进的,第 i 头牛的速度为 Vi.只要有一头奶牛跑完 L 圈之后,比 ...

  7. NC24840 [USACO 2009 Mar S]Look Up

    NC24840 [USACO 2009 Mar S]Look Up 题目 题目描述 Farmer John's N (1 <= N <= 100,000) cows, convenient ...

  8. USACO翻译:USACO 2012 JAN三题(3)

    USACO 2012JAN(题目三) 一.题目概览 中文题目名称 放牧 登山 奶牛排队 英文题目名称 grazing climb lineup 可执行文件名 grazing climb lineup ...

  9. USACO 2012 Feb Cow Coupons

    2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...

随机推荐

  1. 通过Nginx TCP反向代理实现Apache Doris负载均衡

    概述 Nginx能够实现HTTP.HTTPS协议的负载均衡,也能够实现TCP协议的负载均衡.那么,问题来了,可不可以通过Nginx实现Apache Doris数据库的负载均衡呢?答案是:可以.接下来, ...

  2. HttpServletResponse & HttpServletRequest

    web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse: 如果要获取客户端请求过来的 ...

  3. 项目文章|DNA(羟)甲基化研究揭示铁离子依赖表观调控促进狼疮致病性T细胞分化|易基因

    易基因(羟)甲基化DNA免疫共沉淀测序(h)MeDIP-seq研究成果见刊<Journal of Clinical Investigation> 2022年5月2日,中南大学湘雅二医院赵明 ...

  4. 让服务调用更简单 - Caller.HttpClient

    前言 绝大多数项目都离不开服务调用,服务的调用方式通常是基于Http.RPC协议的调用,需要获取到对应服务的域名或者ip地址以及详细的控制器方法后才能进行调用,如果项目需要支持分布式部署,则需要借助服 ...

  5. mapstruct 的 mapstruct-processor 自动生成的 Impl 文件中未设置属性值(时好时坏)

    配置依赖和注解处理器 ... <properties> <org.mapstruct.version>1.4.2.Final</org.mapstruct.version ...

  6. 【mq】从零开始实现 mq-11-消费者消息回执添加分组信息 pull message ack groupName

    前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...

  7. MySQL(8) - MySQL的事务机制

    MySQL数据库的事务机制 1.1.事务的概念和特性 1.2.事务的隔离级别 repeatable read是mysql默认的事务隔离级别 #事务A #事务A,临时修改工资,未commit, STAR ...

  8. 好客租房39-react组件基础总结

    1组件的两种创建方式:函数组件和类组件 2无状态函数组件 负责静态结构展示 3有状态组件 负责更新ui 让页面动起来 4绑定事件注意this指向问题 5使用受控组件创建表单 6完全利用js语言的能够力 ...

  9. 个人冲刺(六)——体温上报app(一阶段)

    任务:完成了自动获取定位信息以及自动获取时间功能 自动获取定位信息 public void onReceiveLocation(BDLocation location){ //此处的BDLocatio ...

  10. mysql查询关键字补充与多表查询

    目录 查询关键字补充 having过滤 distinct去重 order by排序 limit分页 regexp正则 多表查询 子查询 连表查询 查询关键字补充 having过滤 关键字having和 ...