思路
这道题最后推出来矩阵的平均值,其实就是横向平均值的最大值+列项平均值的最大值
那么我们就可以用二分答案(本问题的答案具有单调性)
对于每一个数组中的每一个元素枚举a[i]-mid的前缀和,来找这个序列中是否存在大于我们规定数组长度的前缀和大于0的,如果存在那么我们就继续往大二分,反之,就说明我们的mid取大了就往小里来二分。
#include<iostream>
#include<cstring>
using namespace std;
const double eps=1e-6;
double a[2102100];
double b[2102100];
double sum[2102100];
int n,m,x,y;
int check(double mid,bool limit){
double t=-1e9;
int ju=0;
double minn;
if(limit){
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i]-mid;
minn=1e9;
for(int i=x;i<=n;i++){
if(sum[i-x]<minn){
minn=min(sum[i-x],minn);
}
t=max(t,sum[i]-minn);
}
}else{
for(int i=1;i<=m;i++)sum[i]=sum[i-1]+b[i]-mid;
minn=1e9;
for(int i=y;i<=m;i++){
if(sum[i-y]<minn){
minn=min(sum[i-y],minn);
}
t=max(t,sum[i]-minn);
}
}
return t<0;
}
double bsearch(double l,double r,bool limit){
double mid=(l+r)/2;
while(r-l>=eps){
mid=(l+r)/2;
if(check(mid,limit))r=mid;
else l=mid;
}
return l;
}
signed 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];
double lie=bsearch(0,10000000,1);
double hang=bsearch(0,10000000,0);
printf("%.10lf",hang+lie);
}