NC24325 [USACO 2012 Mar S]Flowerpot
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的更多相关文章
- [USACO 2012 Mar Silver] Landscaping【Edit Distance】
传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=126 好题啊好题,一开始就输给了这道题的想法! 先把原始状态以及目标状态换 ...
- [USACO 2012 Mar Gold] Large Banner
传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢 ...
- USACO翻译:USACO 2012 FEB Silver三题
USACO 2012 FEB SILVER 一.题目概览 中文题目名称 矩形草地 奶牛IDs 搬家 英文题目名称 planting cowids relocate 可执行文件名 planting co ...
- USACO翻译:USACO 2012 JAN三题(2)
USACO 2012 JAN(题目二) 一.题目概览 中文题目名称 叠干草 分干草 奶牛联盟 英文题目名称 stacking baleshare cowrun 可执行文件名 stacking bale ...
- USACO翻译:USACO 2012 JAN三题(1)
USACO 2012 JAN(题目一) 一.题目概览 中文题目名称 礼物 配送路线 游戏组合技 英文题目名称 gifts delivery combos 可执行文件名 gifts delivery c ...
- 【USACO 2012 Open】Running Laps(树状数组)
53 奶牛赛跑 约翰有 N 头奶牛,他为这些奶牛准备了一个周长为 C 的环形跑牛场.所有奶牛从起点同时起跑,奶牛在比赛中总是以匀速前进的,第 i 头牛的速度为 Vi.只要有一头奶牛跑完 L 圈之后,比 ...
- NC24840 [USACO 2009 Mar S]Look Up
NC24840 [USACO 2009 Mar S]Look Up 题目 题目描述 Farmer John's N (1 <= N <= 100,000) cows, convenient ...
- USACO翻译:USACO 2012 JAN三题(3)
USACO 2012JAN(题目三) 一.题目概览 中文题目名称 放牧 登山 奶牛排队 英文题目名称 grazing climb lineup 可执行文件名 grazing climb lineup ...
- USACO 2012 Feb Cow Coupons
2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...
随机推荐
- 2021.07.09 K-D树
2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...
- Arch Linux 安装简明流程
Arch Linux 安装简明流程 这是一篇为 GPT/EFI 引导 的电脑安装 Arch Linux(双系统)的中文简明流程,尽可能省略了可以省略的流程与文字以使得篇幅尽量短小,基本上基于 Arch ...
- 攻防世界-MISC:2017_Dating_in_Singapore
这是MISC高手进阶区的题目:题目如下: 点击下载附件一,得到一张pdf图片,除此之外就只有题目给的字符串了,不知道是什么意思(查看了一下WP)原来每一串通过"-"隔开的字符串代表 ...
- ucore lab1 操作系统启动过程 学习笔记
开头赞美THU给我们提供了这么棒的资源.难是真的难,好也是真的好.这种广查资料,反复推敲,反复思考从通电后第一条代码搞起来理顺一个操作系统源码的感觉是真的爽. 1. 操作系统镜像文件ucore.img ...
- insert语句生成的存储过程
问题: 1.如何配置数据库数据: 方式一:图形界面点击输入数据,导出成sql. 缺点:表多,数据多的时候非常繁琐,字段含义需要另外开窗口对照. 方式二:徒手写或者修改已有语句:insert table ...
- 将Excel数据转换为Java可识别时间(Date、Timestamp)
引言 Excel的时间,POI读取到的是double,这个值不是timestamp.需要进行一些转换,将它转换为Date或者Timestamp. Excel中的日期数据: 程序中读取到的数据: 如何转 ...
- 【mq】从零开始实现 mq-07-负载均衡 load balance
前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...
- 太极限了,JDK的这个BUG都能被我踩到
hello,大家好呀,我是小楼. 之前遇到个文件监听变更的问题,刚好这周末有空研究了一番,整理出来分享给大家. 从一次故障说起 我们还是从故障说起,这样更加贴近实际,也能让大家更快速理解背景. 有一个 ...
- mysql二进制日志和mysql备份工具介绍以及日志恢复
mysql备份: 三种备份方式 冷备:数据库停机,在进行备份 热备:lock table锁表,read 数据库只可以读不能写,在备份 温备:备份时数据库正常运行 备份类型:完整备份:全部备份,部分 ...
- 299. Bulls and Cows - LeetCode
Question 299. Bulls and Cows Solution 题目大意:有一串隐藏的号码,另一个人会猜一串号码(数目相同),如果号码数字与位置都对了,给一个bull,数字对但位置不对给一 ...