poj2823 Sliding Window

poj2823 Sliding Window

使用单调队列

#include <stdio.h>
#define MAXN 1000001

int n,k;
int pre1,pre2,lst1,lst2;//两个队列的首尾指针
int len_max,len_min;//最大值和最小值的下标

int num[MAXN];
int Increase[MAXN],Decrease[MAXN];//单调递增和递减序列,存放序号
int Max[MAXN],Min[MAXN];//最大值和最小值数组

void in_max(int i){//更新递增序列
    while (pre1<=lst1&&num[Increase[lst1]]<num[i]) {
        --lst1;//尾指针前移
    }
    Increase[++lst1]=i;//添加新的元素的序号
    
    //如果大于等于k个数,就需要向最大值数组赋值
    if (i>=k) {
        if (Increase[pre1]<=i-k) {
            ++pre1;
        }
        Max[len_max++]=num[Increase[pre1]];
    }
    
}

void in_min(int i){//更新递减序列
    while (pre2<=lst2&&num[Decrease[lst2]]>num[i]) {
        --lst2;//尾指针前移
    }
    Decrease[++lst2]=i;
    if (i>=k) {
        if (Decrease[pre2]<=i-k) {
            ++pre2;
        }
        Min[len_min++]=num[Decrease[pre2]];
    }
}

int main(){
    int i;
    while (~scanf("%d%d",&n,&k)) {
        //初始化
        pre1=pre2=len_max=len_min=0;
        lst1=lst2=-1;
        
        //读入数据
        for (i=1; i<=n; ++i) {
            scanf("%d",&num[i]);
            in_max(i);
            in_min(i);
        }
        
        //输出数据
        for (i=0; i<len_min-1; ++i) {//输出最小值
            printf("%d ",Min[i]);
        }
        printf("%d\n",Min[len_min-1]);
        
        for (i=0; i<len_max-1; ++i) {//输出最大值
            printf("%d ",Max[i]);
        }
        printf("%d\n",Max[len_max-1]);
    }
    return 0;
}



参考:poj2823


你可能感兴趣的:(poj2823 Sliding Window)