uva 1451 平均值
Posted jack_yyc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva 1451 平均值相关的知识,希望对你有一定的参考价值。
题目大意:
一个01串,求一段长度至少为L的区间使这个区间的平均值最大
思路:
因为是一个01串,所以我们可以把串内的点都当做点来处理
每个点的横坐标为它的位置,而纵坐标则为它的前缀和
这样这个串就变为了一个阶梯式的图像
如果点p在线段AB或BC上,取点i
如果点p在点C上方,取点k
所以点j并没有啥用,我们可以把它删掉了
我们可以枚举每个结尾点
根据上面的结论我们可以删除距离结尾点l外所有上凸点留下一个凸包
对于这个我们可以使用单调队列来实现
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<queue> #include<vector> #define inf 2147483611 #define ll long long #define MAXN 101010 #define MOD using namespace std; inline int read() { int x=0,f=1; char ch;ch=getchar(); while(!isdigit(ch)) {if(ch==\'-\') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-\'0\';ch=getchar();} return x*f; } int n,l,T; int q[MAXN],s[MAXN],head,tail; char x; int cmp(int x1,int x2,int x3,int x4) {return (s[x2]-s[x1])*(x4-x3)-(s[x4]-s[x3])*(x2-x1);} int main() { T=read(); while(T--) { head=tail=0; n=read(),l=read(); for(int i=1;i<=n;i++) { x=getchar(); s[i]=s[i-1]+x-\'0\'; } int al=0,ar=l; for(int i=l;i<=n;i++) { while(head<tail-1&&cmp(i-l,q[tail-1],i-l,q[tail-2])<0) tail--;//当前队尾不需要 q[tail++]=i-l; while(head<tail-1&&cmp(q[head+1],i,q[head],i)>=0) head++;//当前队首不需要 if(cmp(q[head],i,al,ar)>0||(cmp(q[head],i,al,ar)==0&&(i-q[head]<ar-al))) al=q[head],ar=i;//斜率优于答案或斜率相同长度更短 } printf("%d %d\\n",al+1,ar); } }
以上是关于uva 1451 平均值的主要内容,如果未能解决你的问题,请参考以下文章