【题意】给定一个大小已知的数组以及一个大小已知的滑动窗口,窗口每个时刻向后移动一位,求出每个时刻窗口中数字的最大值和最小值。
【分析】第一分单调队列优化的入门题,思路很简单,这里就是维护一个长度最长为k的递增和递减的单调队列!
【AC代码】
// cpp~
//queue dp
#include <queue>
#include <cstdio>
using namespace std;
const int maxn = 1000005;
struct node{
int val,pos;
node(){}
node(int val,int pos):val(val),pos(pos){}
}que1[maxn],que2[maxn];
int maxhead,maxtail,minhead,mintail;
int maxans[maxn],minans[maxn];
int num;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int cur=0;
maxhead=0,maxtail=0;
minhead=0,mintail=0;
for(int i=0; i<k; i++){
scanf("%d",&num);
// min
while(minhead<mintail&&que1[mintail-1].val>=num) mintail--;
que1[mintail] = node(num,i);mintail++;
//max
while(maxhead<maxtail&&que2[maxtail-1].val<=num) maxtail--;
que2[maxtail] = node(num,i);maxtail++;
}
for(int i=k; i<n; i++){
minans[cur] = que1[minhead].val;
maxans[cur] = que2[maxhead].val;
cur++;
scanf("%d",&num);
//min
while(minhead<mintail&&i-que1[minhead].pos>=k) minhead++;
while(minhead<mintail&&que1[mintail-1].val>=num) mintail--;
que1[mintail] = node(num,i);mintail++;
//max
while(maxhead<maxtail&&i-que2[maxhead].pos>=k) maxhead++;
while(maxhead<maxtail&&que2[maxtail-1].val<=num) maxtail--;
que2[maxtail] = node(num,i);maxtail++;
}
minans[cur] = que1[minhead].val;
maxans[cur] = que2[maxhead].val;
cur++;
for(int i=0; i<cur; i++)printf("%d ",minans[i]);
printf("\n");
for(int i=0; i<cur; i++)printf("%d ",maxans[i]);
printf("\n");
return 0;
}