最佳牛围栏
解题思路:对于这种求最大/最小可能是多少可以采用二分法。给定一个值,判断这个值是否满足要求,如果满足,可以把平均值增大/减少。对于check函数,求平均值,因此将数组a都减去这个平均值,在给定F的情况下,只需要有连续的 >= F个数的和 >=0就存在这样的值。
二分的最后要取右端点,因为l,r是浮点数,取左边的话如果值恰好能够取整,那么左边会有精度损失
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e5+10;
const double eps = 1e-7;
int a[N];
double s[N];
int n,m;
bool check(double x)
{
for (int i = 1; i <= n; i ++ )
{
s[i] = s[i-1] + a[i] - x;
}
double mins = 0;
for(int i = m;i<=n;i++)
{
mins = min(s[i-m],mins);
if(s[i] >= mins) return true;
}
return false;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
double l = 0,r = 2000;
while(r - l > eps)
{
double mid = (l + r)/2;
if(check(mid)) l = mid;
else r = mid;
}
cout << (int)(r*1000) << endl;
return 0;
}