例题:(来源:caioj 1172)
标题:给定一个n个数的数列,从左至右输出每个长度为m的数列段内的最大数。
思路:
单调队列的应用:用来解决区
间最值问,当我们访问到a[i]时
前m-1个数的最大值已经被记录
操作过程就是不断维护一个单调递减的队列
为什么要递减:队列最左边头部最大的数为
i-n到i区间的最大数当区间爆满(范围大于n了)
就会掐头区间的范围会在a[i]上整体右移
这时的头部就比以前的头部小一点此数就是新区间的最大值;
下面展示一些 内联代码片
。
6 3
8 9 7 6 5 4
#include<stdio.h>
#include<string.h>
int a[100001];
struct que
{
int x,ii;
}q[11000];
int main()
{
int n,m,j,i,k,head=1,tail=1;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
q[1].x=a[1];
q[1].ii=1;
for(i=2;i<=n;i++)
{
while(head<=tail&&q[tail].x<=a[i])
{
tail--;
}
q[++tail].x=a[i];
q[tail].ii=i;
while(head<=tail&&q[head].ii<i-(m-1))
{
head++;
}
if(i>=m)
printf("%d ",q[head].x);
}
return 0;
}