洛谷 P3088 [USACO13NOV]挤奶牛Crowded Cows 题解

P3088 [USACO13NOV]挤奶牛Crowded Cows

题目描述

Farmer John's N cows (1 <= N <= 50,000) are grazing along a one-dimensional fence. Cow i is standing at location x(i) and has height h(i) (1 <= x(i),h(i) <= 1,000,000,000).

A cow feels "crowded" if there is another cow at least twice her height within distance D on her left, and also another cow at least twice her height within distance D on her right (1 <= D <= 1,000,000,000). Since crowded cows produce less milk, Farmer John would like to count the number of such cows. Please help him.

FJ有N(1 <= N <= 50,000)头奶牛沿着一维的栅栏吃草,第i头奶牛在目标点x(i) ,它的身高是 h(i) (1 <=x(i),h(i) <= 1,000,000,000)。

当一头奶牛左边D距离内而且右边D距离内有身高至少是它的两倍的奶牛,t (1 <= D <= 1,000,000,000),它就会觉得拥挤。

请计算觉得拥挤的奶牛的数量。

输入格式

  • Line 1: Two integers, N and D.

  • Lines 2..1+N: Line i+1 contains the integers x(i) and h(i). The locations of all N cows are distinct.

输出格式

  • Line 1: The number of crowded cows.

输入输出样例

输入 #1复制

6 4
10 3
6 2
5 3
9 7
3 6
11 2

输出 #1复制

2

说明/提示

There are 6 cows, with a distance threshold of 4 for feeling crowded. Cow #1 lives at position x=10 and has height h=3, and so on.

The cows at positions x=5 and x=6 are both crowded.

【思路】

单调队列

【题目分析】

每一头牛都有两边的d长度的的区间
只要两边的区间内都有大于等于这头牛两倍身高的牛
那他就会觉得拥挤
求觉得拥挤的牛的数量

【前缀思想】

有身高至少是它的两倍的奶牛?
这完全可以之比较最高的那头奶牛啊?
只要最高的比他的两倍高
那就至少是有的了
如果最高的不如他的两倍高
那一定没有比他两倍高的
所以比较最高的就可
区间最大值?
当然是单调队列
但是两个区间?
那就两个单调队列!

【最终思路】

顺着扫一遍处理出每一个点左边区间内
最高的那头牛
倒着扫一遍处理出每一个点右边区间内
最高的那头牛
(这里区间指的都是合法区间即长度小于等于d的区间)
然后在扫一遍每一个点
看看是不是两倍都有比自己的身高高两倍的牛
如果有那就计数
如果没有那就继续

【完整代码】

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<deque>
using namespace std;
const int Max = 50004;
struct node
{
	int x;
	int h;
}a[Max];
bool cmp(const node x,const node y)
{
	return x.x < y.x;
}
deque<node>q1,q2;
int l[Max],r[Max];
int main()
{
//	freopen("cow.in","r",stdin);
	int n,d;
	cin >> n >> d;
	for(register int i = 1;i <= n;++ i)
		cin >> a[i].x >> a[i].h;
	sort(a + 1,a + 1 + n,cmp);
	for(register int i = 1;i <= n;++ i)
	{
		while(!q1.empty() && a[i].x - q1.front().x > d)
			q1.pop_front();
		if(!q1.empty())
			l[i] = q1.front().h;
		else
			l[i] = 0;
		while(!q1.empty() && a[i].h > q1.back().h)
			q1.pop_back();
		q1.push_back(a[i]);
	}
	for(register int i = n;i >= 1;i --)
	{
		while(!q2.empty() && q2.front().x - a[i].x > d)
			q2.pop_front();
		if(!q2.empty())
			r[i] = q2.front().h;
		else
			r[i] = 0;
		while(!q2.empty() && a[i].h > q2.back().h)
			q2.pop_back();
		q2.push_back(a[i]);
	}
	int js = 0;
	for(register int i = 1;i <= n;++ i)
		if(l[i] >= a[i].h * 2 && r[i] >= a[i].h * 2)
			js ++;
	cout << js << endl;
	return 0;
}
原文地址:https://www.cnblogs.com/acioi/p/11689817.html