2021牛客多校第四场补题

J.Average

题目思路

我们根据题目给出的条件可以推出最后的值应该等于 s u m a x + s u m b y \frac{sum_a}{x}+\frac{sum_b}{y} xsuma+ysumb
问题就变成了a数组上找一个长度不小于x的区间最大平均值加上b数组上找一个长度不小于y的区间最大平均值
考虑二分平均值求解。
每次check,先将数组前缀和求出,然后枚举右端点i,并且维护左端点j,保证j<=i-x,并且前缀和最小,最后判断sum[i]-sum[j]的值是否大于等于0。

ac代码


int n,m,x,y;
double a[maxn],b[maxn];
double c[maxn];

bool checka(double xx,double z[],int x,int len)
{
    c[0]=0;
    for(int i=1;i<=len;i++)
        c[i]=z[i]-xx;
    for(int i=1;i<=len;i++)
    {
        c[i]=c[i]+c[i-1];
        if(c[i]>0&&i>=x)return 1;
    }
    double mi=0;
    for(int i=x+1;i<=len;i++)
    {
        mi=min(mi,c[i-x]);
        if(c[i]-mi>=eps)
        {
            return 1;
        }
    }

    return 0;
}



int main()
{
    cin>>n>>m>>x>>y;
    for(int i=1;i<=n;i++)
    {
        scanf("%lf",&a[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%lf",&b[i]);
    }
    double l=0.0,r=1e5;
    double ansl=0;
    while(r-l>eps)
    {
        double mid=(r+l)/2;
        if(checka(mid,a,x,n))
        {
            l=mid;

        }else
        {
            r=mid;
        }
    }
    ansl=l;
    l=0.0,r=1e5;
    double ansr=0;

    while(r-l>eps)
    {
        double mid=(r+l)/2;
        if(checka(mid,b,y,m))
        {
            l=mid;

        }else
        {
            r=mid;
        }
    }
    ansr=l;
    printf("%lf\n",ansl+ansr);
 	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值