题意:
输入一个串,求长度至少为k且平均值最大的字串的起始与结束位置
思路:
首先累加到每个为的总值,然后再枚举所有可能的终点,然后cur为最近的起点,q存储所有的起点,每次存储起点都要达到作为终点的最优
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100005;
int n, l;
int sum[maxn];
int q[maxn];
char str[maxn];
double ave(int x, int y) {
return (sum[y]-sum[x])*1.0/(y-x);
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
scanf("%d%d", &n, &l);
sum[0] = 0;
scanf("%s", str+1);
for(int i=1; i<=n; i++) {
sum[i] = sum[i-1]+(str[i]-'0');
}
int s=0, f=-1, len=l;
double ans = ave(0, l);
int ansl=0, ansr=l;
for(int i=l; i<=n; i++) {
int cur = i-l;
while(f>s && ave(q[f], cur) <= ave(q[f-1], cur))
f--;
q[++f] = cur;
while(f>s && ave(q[s], i) <= ave(q[s+1], i))
s++;
double b = ave(q[s], i);
if(b > ans) {
ansl = q[s];
ansr = i;
ans = b;
len = i-q[s];
}
else if(b == ans && i-q[s] < len) {
ansl = q[s];
ansr = q[f];
len = i-q[s];
}
}
printf("%d %d\n", ansl+1, ansr);
}
return 0;
}
(不能达到最优的自然可以淘汰),然后在q内找到最优的起点最后调整
代码: