滑动窗口
滑动窗口
https://ac.nowcoder.com/acm/problem/50528
首先,单调队列具有两个性质
1.队列中的元素其对应在原来的列表中的顺序必须是单调递增的。
2.队列中元素的大小必须是单调递*(增/减/甚至是自定义也可以)
这个题是单调队列的模板题,因为范围最大时1e6,所以这里直接用数组来模拟队列即可。
1.维护队首(就是如果你已经是当前的m个之前那你就可以被删了,head++)
2.在队尾插入(每插入一个就要从队尾开始往前去除冗杂状态)
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int q1[1000010],q2[1000010];
int a[1000010];
int head,top;
int n,k;
void imax(){
head=1,top=0;
for(int i=1;i<=n;i++){
while(head<=top&&i-q1[head]+1>k) head++;
while(head<=top&&a[q1[top]]<a[i]) top--;
q1[++top]=i;
if(i>=k) printf("%d ",a[q1[head]]);
}
printf("\n");
return ;
}
void imin(){
head=1,top=0;
for(int i=1;i<=n;i++){
while(head<=top&&i-q2[head]+1>k) head++;
while(head<=top&&a[q2[top]]>a[i]) top--;
q2[++top]=i;
if(i>=k) printf("%d ",a[q2[head]]);
}
printf("\n");
return ;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
imin();
imax();
return 0;
}
查看9道真题和解析
