拥挤的奶牛----单调队列

题目描述

FJ的n头奶牛(1<=n<=50000)在被放养在一维的牧场。第i头奶牛站在位置x(i),并且x(i)处有一个高度值h(i)(1<=x(i),h(i)<=1000000000)。

一头奶牛感觉到拥挤当且仅当它的左右两端都有一头奶牛所在的高度至少是它的2倍,且和它的距离最多为D。尽管感到拥挤的奶牛会产生更少的牛奶,FJ还是想知道一共有多上感到拥挤的奶牛。请你帮助他。

输入

第一行:两个整数n和D。

第二行到第n+1行:每一行有两个数表示x(i)和h(i)。

输出

 一个数k表示感到拥挤的奶牛的数量。

样例输入

Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

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

样例输出

2

思路

这道题是典型的单调队列的题。要把每头奶牛遍历一遍,查找它前后D距离以内的不矮于自身高度2倍的牛。这里做一个推导:如果一个范围以内最高的牛都不够高,那它肯定不会觉得拥挤。

所以,分别找每个奶牛前后D距离内最高的奶牛是否不矮于自身高度2倍,再把觉得拥挤的牛统计起来就可以了。

用一个递减单调队列存每个奶牛,每次入牛时把它前面矮于它的奶牛都踢出,还要把队首所有坐标不在距离D范围以内的奶牛出队,最后判断队首的奶牛是否足够高就完了。

这样遍历前、后各一次,两次都觉得拥挤的奶牛才把它加上。

代码如下,以理解的就不用看了。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long int
using namespace std;
LL n,m,i,j,f[50005],l,r,k;
bool v[50005];
struct itn{
    LL x,h;
    itn(){}
    itn(LL X,LL H){
        x=X,h=H;
    }
}cow[50005];
inline LL read(){            //读入优化
    LL x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
inline bool cmp(itn a,itn b){
    return a.x<b.x;
}
int main()
{
    n=read(),m=read();
    for(i=1;i<=n;i++)cow[i].x=read(),cow[i].h=read();
    sort(cow+1,cow+1+n,cmp);
    for(i=1;i<=n;i++){
        while(r>l&&cow[f[l]].x<cow[i].x-m)l++;
        if(r>l&&cow[f[l]].h>=cow[i].h*2)v[i]=1;
        while(r>l&&cow[f[r-1]].h<cow[i].h)r--;
        f[r++]=i;
    }
    l=r=0;
    for(i=n;i>0;i--){
        while(r>l&&cow[f[l]].x>cow[i].x+m)l++;
        if(r>l&&cow[f[l]].h>=cow[i].h*2&&v[i])k++;
        while(r>l&&cow[f[r-1]].h<cow[i].h)r--;
        f[r++]=i;
    }
    printf("%lld",k);
    putchar('\n');
    return 0;
}

欢迎关注我的博客 偶耶(xiong j x)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值