CF 1616D - Keep the Average High

题目链接:

https://codeforces.com/problemset/problem/1616/D

题目大意:

给定一个长度为 \(n\) 的序列和一个 \(x\),选择序列中的一些元素,使序列中所有子区间 \(a_l\),\(a_{l + 1}\),...,\(a_r\) 满足 \(\sum_{i = l}^r\) >= x * (r - l + 1) 或者其中一个及以上的元素未被选择这两个条件,求能选择的元素最多是多少。

思路:

\(\sum_{i = l}^r\) >= x * (r - l + 1) 即 \(l\) 到 \(r\) 的区间内所有的元素的平均数要大于等于 \(x\),于是可以让序列中所有的元素先减去 \(x\),那么该条件就转化为平均数非负就可以了。
一个序列所有子区间都大于 0 的话,只需要所有长度为 2 或 3 的子区间非负就可以了。而要使选择的元素最多,先假设选择了全部的数字,再先考虑非负,若有负,则少选一个数。

代码:
(参考jiangly)

#include <bits/stdc++.h>
using namespace std;
int T, n, ans;
void solve(){
	scanf("%d", &n);
	int ans = n, x;
	vector <int> a(n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	scanf("%d", &x);
	for (int i = 0; i < n; i++)
		a[i] -= x;
	int p = 0;
	for (int i = 1; i < n; i++){
		bool f = false;
		if (i >= 1 && i - p >= 1 && a[i] + a[i - 1] < 0) f = true;
		if (i >= 2 && i - p >= 2 && a[i] + a[i - 1] + a[i - 2] < 0) f = true;
		if (f){
			ans--;
			p = i + 1;
		}
	}
	cout << ans << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}
上一篇:CF 1616D - Keep the Average High


下一篇:如何通过代码实现访问触发频率抵御CC攻击-借助SharkCDN快速部署自定义防护模式