POJ 2823

【题意】给定一个大小已知的数组以及一个大小已知的滑动窗口,窗口每个时刻向后移动一位,求出每个时刻窗口中数字的最大值和最小值。

【分析】第一分单调队列优化的入门题,思路很简单,这里就是维护一个长度最长为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;
}


你可能感兴趣的:(POJ 2823)