问题背景
一本通1.2 例2
题目描述
给定一个长度为 n 的非负整数序列 A ,求一个平均数最大的,长度不小于 L 的子段。
输入格式
第一行用空格分隔的两个整数 n 和 L;
第二行为 n 个用空格隔开的非负整数,表示 Ai。输出格式
输出一个整数,表示答案的 1000 倍。不用四舍五入,直接输出。
样例输入1
10 6
6 4 2 10 3 8 5 9 4 1样例输出1
6500
注释说明
1≤n≤10^5, 0≤Ai≤2000。
#include<bits/stdc++.h>
using namespace std;
int n,l,ans;
double a[100005],h[100005];
bool check(double x){
double d=1e8;
double ans=-1e5;
for(int i=1;i<=n;i++)h[i]=a[i]-x;//,printf("%.3lf ",h[i]);puts("");
for(int i=2;i<=n;i++)h[i]+=h[i-1];
for(int i=l;i<=n;i++){
d=min(d,h[i-l]);
ans=max(ans,h[i]-d);
}
//printf("ans=%.3lf\n",ans);
if(ans<0)return 0;
return 1;
}
int main(){
scanf("%d%d",&n,&l);
for(int i=1;i<=n;i++)scanf("%lf",&a[i]);//,printf("%lf ",a[i]);puts("");
double l=0,r=2001;
while(l+0.001<r){
double mid=(r+l)/2.0;//printf("l=%lf,mid=%lf,r=%lf\n",l,mid,r);//cout<<mid<<"\n";
if(check(mid))l=mid;
else r=mid;
}
ans=r*1000;
cout<<ans;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,f,c[100003],av,ans,q,mq,h,a[100003];
bool check(ll x){
h=-0x3f3f3f3f;
q=0;
for(int i=1;i<=n;i++){
a[i]=c[i]-x;
a[i]+=a[i-1];
}
for(int i=f;i<=n;i++){
q=min(q,a[i-f]);
h=max(h,a[i]-q);
}
//cout<<h<<" ";
if(h>=0)return 1;
return 0;
}
int main() {
scanf("%I64d%I64d",&n,&f);
for(int i=1;i<=n;i++){
scanf("%I64d",&c[i]);
c[i]*=1000;
}
ll l=1,r=2000000;
while(l<=r){
ll mid=(l+r)/2;//printf("%I64d\n",mid);
if(check(mid)){
l=mid+1;
}
else r=mid-1;
}
printf("%I64d",r);
}