J-Average
链接:https://ac.nowcoder.com/acm/contest/11255/J
来源:牛客网
Bob has an n×mn\times mn×m matrix WWW.
This matrix is very special, It's calculated by two sequences a1...n,b1...ma_{1...n},b_{1...m}a1...n,b1...m, ∀i∈[1,n],∀j∈[1,m]\forall i\in [1,n],\forall j\in [1,m]∀i∈[1,n],∀j∈[1,m], Wi,j=ai+bjW_{i,j}=a_{i}+b_{j}Wi,j=ai+bj
Now Bob wants to find a submatrix of WWW with the largest average value.
Bob doesn't want the size of submatrix to be too small, so the submatrix you find must satisfy that the width(the first dimension of matrix) of it is at least xxx and the height(the second dimension of matrix) of it is at least yyy.
Now you need to calculate the largest average value.
输入描述:
The first line has four integers n,m,x,yn,m,x,yn,m,x,y. The second line has nnn integers a1...na_{1...n}a1...n. The third line has mmm integers b1...mb_{1...m}b1...m. 1≤n,m≤1051\leq n,m\leq 10^51≤n,m≤105 1≤x≤n,1≤y≤m1\leq x\leq n,1\leq y\leq m1≤x≤n,1≤y≤m 0≤ai,bi≤1050\leq a_i,b_i\leq 10^50≤ai,bi≤105
输出描述:
Output the largest average value. Your answer will be considered correct if the absolute or relative error is less than 10−610^{-6}10−6
题目大意
每一个单位的值Ci,j =ni+mj 选择一个矩形 使其中的平均ci,j最大,其中保证选中矩形的大小不能小于x行y列
思路
其实题目就转变为对于ni 和mi两个数组 在区间大于给定限制的情况下选择最大的平均值
利用二分去计算 这个平均值
l=min ai ,r=max ai (a数组即m或n数组)
check函数是将所有ai减去mid 然后 遍历1-n 不断记录新的前缀和sum [i]
同时记录最小前缀和 sum[i-k] 令prev =min(pre,sum[i-k])
当sum[i]-prev>0 return 1;
ps:对于eps的选择没必要那么精细 输出只需要输出.6lf就足够了 比赛时样例误导了我
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int a[maxn],b[maxn],suma[maxn],sumb[maxn];
int n,m,x,y;
int pa,pb;
int amax,bmax,amin,bmin;
bool check( double mid,int k) {
double sum = 0, prev = 0, min_sum = 0;
for (int i = 0; i < k; i++)
sum += a[i] - mid;
if (sum >= 0)
return true;
for (int i = k; i < n; i++)
{
sum += a[i] - mid;
prev += a[i - k] - mid;
min_sum = min(prev, min_sum);
if (sum >= min_sum)
return true;
}
return false;
}
bool check1( double mid,int k) {
double sum = 0, prev = 0, min_sum = 0;
for (int i = 0; i < k; i++)
sum += b[i] - mid;
if (sum >= 0)
return true;
for (int i = k; i < m; i++)
{
sum += b[i] - mid;
prev += b[i - k] - mid;
min_sum = min(prev, min_sum);
if (sum >= min_sum)
return true;
}
return false;
}
int main()
{
cin>>n>>m>>x>>y;
amin=inf;
bmin=inf;
for(int i=0;i<n;i++)
{
cin>>a[i];
suma[i]=suma[i-1]+a[i];
amax=max(amax,a[i]);
amin=min(amin,a[i]);
}
for(int i=0;i<m;i++)
{
cin>>b[i];
sumb[i]=sumb[i-1]+b[i];
bmax=max(bmax,b[i]);
bmin=min(bmin,b[i]);
}
//cout<<amin<<amax<<endl;
double ans=0;
double l=(double)amin;
double r=(double)amax;
while(r-l>0.00000001)
{
//cout<<l<<endl;
double mid=(l+r)/2.0;
//cout<<mid<<endl;
if(check(mid,x))
{
l=mid;
}
else r=mid;
}
ans+=l;
//cout<<ans<<endl;
l=(double)bmin;
r=(double)bmax;
while(r-l>0.00000001)
{
double mid=(l+r)/2.0;
if(check1(mid,y))
{
l=mid;
}
else r=mid;
}
ans+=l;
printf("%.7lf\n",ans);
return 0;
}