1 条题解
-
0
问题描述
Farmer John的农场由一排()块田地组成。每块田地里有一定数量的奶牛,。
FJ想要在一块连续的田地周围建一个围栏,以使得该区域内每块田地的平均奶牛数量最大化。这个区域必须包含至少()块田地,其中是给定的输入。
在给定的约束条件下,计算围栏的放置位置,使得平均奶牛数量最大化。
输入
- 第行:两个用空格分隔的整数,和。
- 第行:每行包含一个整数,表示一块田地里的奶牛数量。第行给出第块田地的奶牛数量,第行给出第块田地的奶牛数量,以此类推。
输出
- 第行:一个整数,表示最大平均值的倍。不要进行四舍五入,只需打印出的整数部分。
示例
输入:
10 6 6 4 2 10 3 8 5 9 4 1
输出:
6500
解题思路
为了高效地解决这个问题,我们可以采用二分搜索结合前缀和的方法。具体步骤如下:
- 确定平均值的范围:由于每块田地的奶牛数量在到之间,平均值的可能范围也是到。
- 二分搜索:在到之间进行二分搜索,寻找最大的平均值,使得存在一个长度至少为的连续子数组,其平均值至少为。
- 检查可行性:对于每个,计算前缀和数组,其中。然后检查是否存在一个长度至少为的子数组,其和。
- 维护最小前缀和:为了高效检查,维护一个,表示前个的最小值。如果,则存在满足条件的子数组。
- 输出结果:最终的最大平均值乘以并取整,即为所求。
解决代码
#include <stdio.h> #include <math.h> #include <algorithm> #include <iostream> #include <string.h> #include <queue> #include <stack> #include <map> #include <set> #include <vector> using namespace std; const double dlt=1e-5; int n,L; double a[100007],b[100007],pre[100007]; int main() { scanf("%d%d",&n,&L); for(int i=1; i<=n; i++) { scanf("%lf",&a[i]); } double l=-1e6,r=1e6; while(r-l>dlt) { int k=0; double mi=(l+r)/2; double mins=1e10; for(int i=1; i<=n; i++) { b[i]=a[i]-mi; } for(int i=1; i<=n; i++) { pre[i]=pre[i-1]+b[i]; } for(int i=L; i<=n; i++) {//一边找最小的前缀和,一边进行运算;这个也关键! mins=min(pre[i-L],mins); if(pre[i]-mins>=0) { k=1; l=mi; break; } } if(!k) r=mi; } r=r*1000; printf("%d\n",(int)r); return 0; }
- 1
信息
- ID
- 1019
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者