求平均数最大,长度不小于 L

给定一个长度为 的非负整数序列 ,求一个平均数最大的,长度不小于 的子段。

输入格式
第一行用空格分隔的两个整数 和 ;

第二行为 个用空格隔开的非负整数,表示 。

输出格式
输出一个整数,表示这个平均数的 倍。不用四舍五入,直接输出。

样例
样例输入
10 6
6 4 2 10 3 8 5 9 4 1
样例输出
6500
思路
直接用二分去找最大平均数
代码

#include
#include
#include
#include
using namespace std;
double a[101234],pre[101234],b[101234];
int main()
{
	int n,L,i,j;
	double l,r,jingdu;
	l=-1e6;//极大值 
	r=1e6;//极小值 
	jingdu=1e-6;//精度 
	scanf("%d%d",&n,&L);
	for(i=1;i<=n;i++)
	scanf("%lf",&a[i]);
	while(r-l>jingdu)//l和r很接近,二分到值可以确定 
	{
		double mid=(r+l)/2;//假设最大平均数是mid 
		for(i=1;i<=n;i++)
		{
			b[i]=a[i]-mid;
			pre[i]=pre[i-1]+b[i];//前缀和(除去假设的最大平均数) 
		}
		double maxx=-1e10,minn=1e10;
		for(i=L;i<=n;i++)
		{
			minn=min(minn,pre[i-L]);//最小的前缀 
			maxx=max(maxx,pre[i]-minn);//前缀和(大于L)减去最小的前缀 ,得到连续(大于L)的最大和 
		  //例如前面都是特别小的数,拉胯了从1到n的前缀和,minn就代表前面最小的和,把他减去,maxx就会尽可能大 
		}
		if(maxx>=0)//maxx>0代表假设的mid可以得到 
		l=mid;//寻找比mid更大的 
		else
		r=mid;//找比mid更小的 
	}
	printf("%d\n",int(r*1000));//转换成int型, 
	//printf("%.0lf\n",r*1000);//有个样例过不去,精度高,比样例大1 
	return 0;
}

你可能感兴趣的:(求平均数最大,长度不小于 L)