[思维][枚举]Trapped in the Haybales S 洛谷P3124

59 篇文章 0 订阅
6 篇文章 0 订阅

题目描述

Farmer John has received a shipment of NN large hay bales(1 \le N \le 100,0001≤N≤100,000), and placed them at various locations along the road connecting the barn with his house. Each bale jj has a size S_jSj​ and a distinct position P_jPj​ giving its location along the one-dimensional road.Bessie the cow is currently located at position BB, where there is no hay bale.Bessie the cow can move around freely along the road, even up to the position at which a bale is located, but she cannot cross through this position. As an exception, if she runs in the same direction for DD units of distance, she builds up enough speed to break through and permanently eliminate any hay bale of size strictly less than DD. Of course, after doing this, she might open up more space to allow her to make a run at other hay bales, eliminating them as well.FJ is currently re-painting his house and his barn, and wants to make sure Bessie cannot reach either one (cows and fresh paint do not make a good combination!) Accordingly, FJ wants to make sure Bessie never breaks through the leftmost or rightmost hay bale, so she stays effectively trapped within the hay bales. FJ has the ability to add hay to a single bale of his choosing to help keep Bessie trapped. Please help him determine the minimum amount of extra size he needs to add to some bale to ensure Bessie stays trapped.

输入格式

The first line of input contains NN as well as Bessie's initial position BB.

Each of the next NN lines describes a bale, and contains two integers giving

its size and position. All sizes and positions are in the range 1\ldots 10^91…109.

输出格式

Print a single integer, giving the minimum amount of hay FJ needs to add to

prevent Bessie from escaping. Print -1 if it is impossible to prevent Bessie's

escape.

输入输出样例

输入 #1

5 7
8 1
1 4
3 8
12 15
20 20

输出 #1

4

题意: 有n个障碍物以及一只奶牛,它们都排列在一条直线上,已知每个障碍物的位置以及大小,同时也知道奶牛的初始位置,奶牛可以在两障碍物中间任意移动,在移动时可以与障碍物重叠,当然奶牛也可能冲破障碍物,在冲破障碍物之前奶牛会加速冲刺,当冲刺距离D严格大于障碍物大小时就可以冲破障碍物,障碍物被冲破之后将不复存在。现在想让奶牛困在至少两障碍物中间,求最少需要增大某个障碍物的大小为多少,如果不可能困住就输出-1。

分析: 只能够增加某一个障碍物的大小,因此想到可以枚举增加的是哪一个障碍物。在对各障碍物排序后可以确定奶牛处于哪两个障碍物中间,先枚举奶牛左边第一个障碍物,要想知道它需要增大多少只需枚举奶牛向右能够到达的最远位置,之后枚举奶牛左边第二个障碍物,这时候不需要从头开始向右枚举,只需要从上次枚举到的右端点开始接着枚举就行,因为在冲破左边第一个障碍物后奶牛的冲刺距离更长了,一定能够到达上次到达的最右端,这样时间复杂度就降到了O(n)。对于奶牛右边的障碍物同理,也是枚举一遍,过程中记录答案即可。对于不可能困住的情况,一种是奶牛一开始就在所有障碍物的一侧,另一种是第一次向右/左枚举最远距离时奶牛直接冲了出去,需要根据情况特判。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;

struct node
{
	int h, pos;
}a[100005];

bool cmp(node x, node y)
{
	return x.pos < y.pos;
}

signed main()
{
	int n, p;
	cin >> n >> p;
	for(int i = 1; i <= n; i++)
		scanf("%d%d", &a[i].h, &a[i].pos);
	sort(a+1, a+n+1, cmp);
	int l = 1, r = n, ans = -1;//二分查找第一个大于等于p的点
	while(l <= r)
	{
		int m = l+r>>1;
		if(a[m].pos >= p)
		{
			ans = m;
			r = m-1;
		}
		else
			l = m+1;
	} 
	if(ans == -1 || a[1].pos > p)//p过大或者过小 
	{
		puts("-1");
		return 0;
	}
	//枚举左侧草堆
	int right = ans;//记录最右点 
	int now = ans-1;
	int res = inf; 
	while(true) 
	{
		if(a[right].pos-a[now].pos > a[right].h)
		{
			right++;
			if(right == n+1)
				break;
		}
		else
		{
			res = min(res, max(0, a[right].pos-a[now].pos-a[now].h));
			now--;
			if(now == 0)
				break;
		}
	}
	//枚举右侧草堆
	int left = ans-1;//记录最左点 
	now = ans;
	while(true) 
	{
		if(a[now].pos-a[left].pos > a[left].h)
		{
			left--;
			if(left == 0)
				break;
		}
		else
		{
			res = min(res, max(0, a[now].pos-a[left].pos-a[now].h));
			now++;
			if(now == n+1)
				break;
		}
	}
	if(res == inf)
		puts("-1");
	else
		cout << res;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值