AcWing 102. 最佳牛围栏
原题链接
简单
作者:
Anoxia_3
,
2020-05-06 10:40:13
,
所有人可见
,
阅读 674
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int cows[N];
double sum[N];
double l , r;
int n , m;
bool check(double avg)//这里用到求平均数的一个技巧,如果要求一个数列的平均数是否大于等于avg,则先将该数列整体减去avg
{ //再求该数列的和是否非负即可
for(int i = 1 ; i <= n ; i++) sum[i] = sum[i - 1] + cows[i] - avg;
//这里求的是cows数组中的某一段,因此可以用前缀和判断即:sum[j]-sum[i]>=0 -> sun[j] >= sum[i]
//i的范围是所求区间的前面即:0~j-m,因此只要一个变量存储sum[0]~sum[j-m]范围内的最小值即可,每次判断sum[j]和minx
double minx = 0;
for(int i = 0 , j = m ; j <= n ; i++ , j++)
{
minx = min(minx , sum[i]);
if(sum[j] > minx) return true;
}
return false;
}
int main()
{
cin >> n >> m;
for(int i = 1 ; i <= n ; i++) cin >> cows[i] , r = max(r , (double)cows[i]);
//对高度进行二分,题目中的精度是10^3,因此while中的判断开到5次方
while(r - l > 1e-5)
{
double mid = (r + l) / 2;
if(check(mid)) l = mid;
else r = mid;
}
cout << int(r * 1000) << endl;//最后将结果转换
return 0;
}