poj 2823 单调队列

来源:互联网 发布:淘宝自动抢单软件 编辑:程序博客网 时间:2024/06/07 22:24
//单调队列求滑动窗口的最大值和最小值//题意是给一个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();    }}

0 0
原创粉丝点击