其他分享
首页 > 其他分享> > #1892. 最美味面包(bread)

#1892. 最美味面包(bread)

作者:互联网

题目链接:

http://39.98.219.132/problem/1892

题目大意:

总共 n 个数,在其中选择长为 [s, t] 的一段连续数字,找出最大的一段的平均值(即这段数字之和 / 数字的数量)。

思路:

首先考虑 暴力,通过 前缀和 求出每个区间的平均值,时间复杂度 O(n * n),40分
优化,最后的取值只可能在 -10000 到 10000 之间,于是我们考虑 二分答案 去猜最大平均值,接下来就是怎样 验证 猜测的最大值。
我们将每个数字都减去平均值,当所有区间的前缀和都等于 0 时,猜测正确,如果有区间的前缀和的值 < 0 时,猜测过大,否则猜测过小

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int n, t, s;
double l, r;
vector <double> num(maxn), sum(maxn);
bool judge(double x){
	for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + num[i] - x;
	deque <int> q;
	for (int i = 0; i <= n - s ; i++){
		while (!q.empty() && sum[i] < sum[q.back()]) q.pop_back();
		q.push_back(i);
		while (!q.empty() && q.front() + t - s < i) q.pop_front();
		if (sum[i + s] > sum[q.front()]) return false;
	}
	return true;
}
int main(){
	cin >> n >> s >> t;
	for (int i = 1; i <= n; i++) scanf("%lf", &num[i]);
	l = -1e4, r = 1e4;
	while (r - l > 1e-5){
		double mid = (l + r) / 2;
		if (judge(mid)) r = mid - 0.00001;
		else l = mid + 0.00001;
	}
	printf("%.3lf\n", l);
	return 0;
}

标签:return,平均值,int,double,mid,maxn,美味,1892,bread
来源: https://www.cnblogs.com/Hamine/p/15532812.html