码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2823 单调队列

时间:2015-07-22 22:44:19      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:poj 2823   单调队列   

//单调队列求滑动窗口的最大值和最小值
//题意是给一个n个数,在每k个数区间内
//求最大值和最小值

//单调队列:队列中的元素是单调的。
//求最小值的时候:进队的时候将队尾部大于当前要进的元素全部出队
//这样,队列的头部就是最小值
//反之,求最大值也是一样


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e6 + 8;
int a[maxn];
int n,k;
int vmi[maxn];
int vmx[maxn];
int deq[maxn];

void input(){
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
}

void getmin(){
    int head=0,tail=0;
    int cnt = 0;
    for (int i=1;i<=n;i++){
        while(tail > head && a[deq[tail-1]]>=a[i])
            tail--;
        deq[tail++] = i;

        if (i-k+1>=0){
            vmi[i-k+1] = a[deq[head]];
            if (i - k + 1 == deq[head]) // 这里的意思是最小值是第x个区间的最左边的值,这个值不在求的
                                        //下一个区间内
                head++;
        }
    }
}

void getmax(){
    int head = 0,tail = 0;
    int cnt = 0;
    for (int i=1;i<=n;i++){
        while (tail > head && a[deq[tail-1]] <= a[i])
            tail--;
        deq[tail++] = i;

        if (i-k+1>=0){
            vmx[i-k+1] = a[deq[head]];
            if (i-k+1 == deq[head]){ // 这里的意思是最小值是第x个区间的最左边的值,这个值不在求的
                                     //下一个区间内
                head ++ ;
            }
        }
    }
}

void print(int a[]){
    for (int i=1;i<=n-k+1;i++){
        printf("%d%c",a[i],(i==n-k+1)?'\n':' ');
    }
}

void solve(){
    getmax();
    getmin();
    print(vmi);
    print(vmx);
}

int main(){
    //freopen("1.txt","r",stdin);
    while(scanf("%d %d",&n,&k)!=EOF){
        input();
        solve();
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

poj 2823 单调队列

标签:poj 2823   单调队列   

原文地址:http://blog.csdn.net/timelimite/article/details/47011075

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!