由于数据范围比较迷,所以数组开一维就好,即二维抽象成一维。注意精度,注意long long,二分答案,sum[i][j]记录第几列深度为多少的前缀和,h[i]记录一共挖了多少深度。那么一定有 平均值x==sum[i][j]/h[i]>=0,移项化简易得sum[i][j]-h[i]*x>=0。二分验证这个式子成立即可。
当时做题的时候比较迷,打了一个错误的暴力。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int h,n,num[110000];
long long sum[110000];
double l=0,r,mid,s,mx;
int main()
{
scanf("%d%d",&n,&h);
for(int i=1;i<=n;i++)
for(int j=1;j<=h;j++)
{
int k=(i-1)*h+j;
scanf("%d",&num[k]);
if(num[k]>r) r=num[k];
if(j!=1) sum[k]=sum[k-1]+num[k];
else sum[k]=num[k];
}
while (r-l>0.000001)
{
mid=(r+l)/2;
s=0;
for(int i=1;i<=n;i++)
{
mx = -2147483645;
for(int j=1;j<=h;j++)
mx=max(mx,sum[(i-1)*h+j]-j*mid);
s+=mx;
}
if(s>=0) l=mid;
else r=mid;
}
printf("%.4lf",mid);
return 0;
}
/*
4 3
4 3 3
5 1 6
2 6 1
3 2 9
*/