POJ 2018. Best Cow Fences
有关数据#
题目大意#
给定长度为 正整数数列 , 求一个平均数最大的、长不小于 的(连续的)子段。
提示#
解法分析#
二分答案,将问题转换为是否存在一个平均数小于
且长度不小于
的子段
。
如果把序列上的每个数都减去 ,则问题转化成寻找和大于等于 且长度不小于 的子段。
考虑 的做法。我们需要求出所有长度符合条件的子段中和最大的,存不存在全看这个最大的和是否非负。(很容易理解吧)那么,枚举字段左右区间,答案就是 。
显然时间复杂度不允许。注意到左边的 可以在第一层循环 里递推求出。
所以,我们就可以 解决 的问题。至此,整道题就解决了。
AC Code#
# include <iostream>
using namespace std;
# define ll long long
# define lf double
# define int ll
# define GO(i,a,b) for(ll i = a; i <= b; i ++)
# define RO(i,b,a) for(ll i = b; i >= a; i --)
# define FO(i,u,head,e) for(int i = head[u]; i; i = e[i].next)
# define CI const int
# define pii pair<int,int>
# define MP(a,b) make_pair(a, b)
# define PB push_back
# define mem(a,x) memset(a, x, sizeof a)
# define F first
# define S second
CI maxn = 1e6 + 7;
int n, k;
lf a[maxn];
lf b[maxn];
lf sum[maxn];
signed main(){
cin >> n >> k;
GO (i, 1, n) scanf("%lf", &a[i]);
lf l = -1e6, r = 1e6;
lf eps = 1e-5;
while (r - l > eps){
lf mid = (l + r) / 2.0;
GO (i, 1, n) b[i] = a[i] - mid;
GO (i, 1, n) sum[i] = sum[i - 1] + b[i];
lf chk = -2e18;
lf min_val = 2e18;
GO (i, k, n){
min_val = min(min_val, sum[i - k]);
chk = max(chk, sum[i] - min_val);
}
if (chk >= 0){
l = mid;
}
else{
r = mid;
}
}
cout << (int)(r * 1000);
return 0;
}
作者:DE_aemmprty
出处:https://www.cnblogs.com/aemmprty/p/BestCowFences.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库