[USACO12MAR]花盆Flowerpot

本文介绍了一种使用二分查找与单调队列优化解决特定类型问题的算法思路。通过实例讲解如何处理雨滴下落时间差问题,利用单调队列维护最大值与最小值,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题面描述

传送门

思路

观察完题意之后,我们看到最小

就会想到二分枚举花盆长度 x x x,需要用两个队列来维护最大值与最小值。

我们检测 [ i , i − x + 1 ] [i,i-x+1] [i,ix+1]中是否有两个水滴下落时间之差是否 ≥ D \ge D D(考虑取纵坐标之差极值)

那么我们往右移一个单位区间变为 [ i + 1 , i − x + 2 ] [i+1,i-x+2] [i+1,ix+2],继续检测。

由于具有单调性,所以我们可以用单调队列优化这个过程。

先将横坐标排序。

bool cmp(node a,node b){return a.x<b.x;}

判断两个雨滴是否可以被接到

while(l1<=r1&&a[i].x-a[q1[l1]].x>x)++l1;
while(l2<=r2&&a[i].x-a[q2[l2]].x>x)++l2;

我们需要比较在合法前提下,也就是在队列中,时间最长的雨滴与时间最短的雨滴之差,是否
大于 D D D

if(a[q1[l1]].y-a[q2[l2]].y>=d)

进入队列的最优状态

while(l1<=r1&&a[q1[r1]].y<=a[i].y)--r1;
while(l2<=r2&&a[q2[r2]].y>=a[i].y)--r2;

关于最大值的维护,如果队尾的值比当前值还小,而且队尾的位置一定在现在位置之前,那么对后面状态的贡献小于当前位置,可以踢出队尾。

最小值的维护类似。

AC code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define gc getchar()
using namespace std;
const int N=1e6+10;
inline int mymin(int x,int y){return x<y?x:y;}
inline int mymax(int x,int y){return x>y?x:y;}
inline void qr(int &x)
{
	x=0;char c=gc;
	while(c<'0'||c>'9')c=gc;
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
}
void qw(int x)
{
	if(x/10)qw(x/10);
	putchar(x%10+48);
}
struct node{int x,y;}a[N];
bool cmp(node a,node b){return a.x<b.x;}
int q1[N],q2[N],l1,r1,l2,r2,n,d;
bool check(int x)
{
	l1=r1=l2=r2=1;q1[1]=q2[1]=0;
	for(int i=1;i<=n;i++)
	{
		while(l1<=r1&&a[i].x-a[q1[l1]].x>x)++l1;
		while(l2<=r2&&a[i].x-a[q2[l2]].x>x)++l2;
		while(l1<=r1&&a[q1[r1]].y<a[i].y)--r1;
		while(l2<=r2&&a[q2[r2]].y>a[i].y)--r2;
		q1[++r1]=i,q2[++r2]=i;
		if(a[q1[l1]].y-a[q2[l2]].y>=d)return true;
	}
	return false;
}
int main()
{
	qr(n),qr(d);int l=1e9,r=0;
	for(int i=1;i<=n;i++)qr(a[i].x),qr(a[i].y),l=mymin(l,a[i].y),r=mymax(r,a[i].y);
	r=r-l;l=0;
	if(r<d)
	{
		puts("-1");return 0;
	}
	sort(a+1,a+n+1,cmp);
	r=a[n].x-a[1].x;
	while(l<r)
	{
		int mid=(l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	qw(l);puts("");
	return 0;
}
目前尚未有 USACO Silver 2025 March 的具体题目和官方题解发布,因为该时间点可能超出了当前已有的竞赛记录范围。然而,可以基于以往的 USACO Silver 级别的题目特点以及常见的算法知识点来推测潜在的内容。 USACO Silver 级别通常涉及的数据结构和算法包括但不限于:前缀和、滑动窗口、二分查找、贪心策略、并查集、BFS/DFS 和简单动态规划等[^3]。以下是关于如何准备类似级别比赛的一些建议: ### 常见问题类型分析 #### 数据处理与模拟 一些题目会测试选手对于复杂输入的理解能力以及基本逻辑实现的能力。例如,在某些场景下需要解析多组数据或者按照特定顺序执行操作。这类问题往往不需要复杂的理论基础,但要求程序具有良好的鲁棒性和效率。 #### 贪婪算法应用 当面对资源分配类的问题时,贪婪方法通常是首选解决方案之一。通过局部最优选择逐步构建全局最佳方案是一种常见思路。比如安排奶牛吃谷物的例子就体现了这一原则[^1]。 #### 图论基础知识 图遍历技术如广度优先搜索(BFS) 或者深度优先搜索(DFS),还有最短路径计算等问题也是Silver阶段的重要组成部分。拖拉机那道题就是一个很好的例子展示了如何利用双端队列优化传统BFS过程从而提高性能表现[^2]。 ```python from collections import deque def bfs_with_deque(start_node, adjacency_list): queue = deque([start_node]) visited = set() while queue: current = queue.popleft() if current not in visited: visited.add(current) for neighbor in adjacency_list[current]: if neighbor not in visited: queue.append(neighbor) return visited ``` ### 准备建议 为了更好地应对未来的USACO赛事,推荐定期练习过往真题,并深入理解每种核心概念背后的工作机制及其适用场合。同时也要注意培养代码调试技巧,这对于快速定位错误至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值