题面:已知a[],b[],矩阵w[i][j]=a[i]+b[j],求矩阵的最大平均数,并且长不小于x,宽不小于y。
解析:易得average=图片说明
两者互不干扰,分别求二者的最大值即可。穷举会T,这道题可以用二分。

二分check函数写法:

我们要找的是 有没有一段不小于x的区间,使这段区间的平均数尽可能的大,如果我们找到了一段连续的区间且区间长度不小于x且平均数大于我们二分的平均数 那么大于这个数且区间也满足的一定满足了 我们直接判断正确即可

对于一段区间,每个数减去我们所算的平均数,如果大于0 那么他本身就大于平均数,如果小于0 那么它本身就小于平均数 此时我们就能算出哪些数大于0 哪些数小于0 ,之后我们再使用前缀和,就能判断一个区间内的平均值是否大于或小于我们二分的平均数了

对于满足区间长度不小于x,我们这里可以使用双指针的做法,我们设i=x,j=0, 每次使两个数++ 因此i,j始终满足相距FF的距离,所以我们用一个变量mi来存储所遍历到的最小值,这样我们比较的距离一定是≥F的,并且如果我们用前i位的前缀和减mi的话,就能得到我们的最优解,如果这个最优解> 0 那么就满足我们的指定条件

最佳牛围栏 借鉴大佬的思路!!!
代码

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
double a[100005],b[100005];
double v[100005];
int check(double mid,double *a,int x,int n){
    for(int i=1;i<=n;i++)
    v[i]=a[i]+v[i-1]-mid;
    double mi=v[0];
    for(int i=x,j=0;i<=n;i++,j++){
    mi=min(mi,v[j]);
        if(v[i]-mi>0) return 1;

    }
    return 0;
}
double fen(double *a,int x,int n){
    double l=0,r=1e5;

    for(int i=0;i<=1000;i++){
        double mid=(l+r)/2;
        if(check(mid,a,x,n)) l=mid;
        else r=mid;
    }
    return (r+l)/2;
}
int main(){
    cin>>n>>m>>x>>y;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++) cin>>b[i];
    printf("%.10lf\n",fen(a,x,n)+fen(b,y,m));
}