acwing 161牛围栏

题目描述

农夫约翰的农场由 N 块田地组成,每块地里都有一定数量的牛,其数量不会少于 1 头,也不会超过 2000 头。

约翰希望用围栏将一部分连续的田地围起来,并使得围起来的区域内每块地包含的牛的数量的平均值达到最大。

围起区域内至少需要包含 F 块地,其中 F 会在输入中给出。

在给定条件下,计算围起区域内每块地包含的牛的数量的平均值可能的最大值是多少

第一行输入整数 N 和 F,数据间用空格隔开。

接下来 N 行,每行输入一个整数,第 i+1 行输入的整数代表第 i 片区域内包含的牛的数目。
输出一个整数,表示平均值的最大值乘以 1000 再 向下取整 之后得到的结果。
数据范围
1≤N≤100000
1≤F≤N

样例

10 6
6 
4
2
10
3
8
5
9
4
1
输出样例:
6500

算法1

(浮点数二分+前缀和+双指针) 

时间复杂度

参考文献

y总

C++ 代码

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,f;
int s[N];
double q[N];
bool ch(double mid){
    double Min=0;
    for(int i=1;i<=n;i++)
    q[i]=q[i-1]+s[i]-mid;//牛数量前缀和减去mid的区间前缀和减去mid求和。
    for(int i=0,j=f;i<n,j<=n;j++,i++)//j从f开始,保证了“围起区域内至少需要包含 F 块地”的条件(双指针)
    {
     Min=min(Min,q[i]);//前i个的最小前缀和
    if(q[j]>=Min)//等价于q[j]-Min>=0,如果前j个的前缀和非负,则存在
    return true;
    }
    return false;
}
int main(){
    cin>>n>>f;
    for(int i=1;i<=n;i++)
    cin>>s[i];
    double l=0,r=2000;
     double mid;
    while(r-l>1e-6)//浮点数二分(如果不熟悉的可以看看Y总视频),此处也可写成for(int i=0;i<100;i++)
    {              //因为*1000实际上保留3位有效位数,所以写成1e-5,1e-6都可。                                    
        mid=(l+r)/2;//将牛的数量进行二分
        if(ch(mid))
        l=mid;//存在j区间,将左段点移至当前mid处,继续向右找最大值
        else
        r=mid;//否则将右端点移至当前mid处,继续向左找最大值
    }
    cout<<int(r*1000);//向下取整
    return 0;
}

路过的客官,可否小小的赞一下,鼓励我这个菜鸡一下,嘿嘿。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值