1. 程式人生 > >POJ 2823 單調佇列

POJ 2823 單調佇列

//
//poj2823(單調佇列)
//給定一個大小已知的陣列以及一個大小已知的滑動視窗,視窗每個時刻向後移動一位,求出每個時刻視窗中數字的最大值和最小值。
//這個題是單調佇列的入門題。
//求最大值:建立一個單調遞減佇列,元素從左到右依次入隊,入隊之前必須從佇列尾部開始刪除那些比當前入隊元素小或者相等的元素,
//直到遇到一個比當前入隊元素大的元素,
//或者佇列為空為止。若此時佇列的大小超過視窗值,則從隊頭刪除元素,直到佇列大小小yu視窗值為止。然後把當前元素插入隊尾。
//
//求最小值:建立一個單調遞增佇列,元素從左到右依次入隊,入隊之前必須從佇列發問開始刪除那些比當前入隊元素大或者相等的元素,
//直到遇到一個比當前入隊元素小的元素,或者佇列為空為止。若此時佇列的大小超過視窗值,則從隊頭刪除元素,直到佇列大小小入視窗值為止。
//然後把當前元素插入隊尾。
//
//設視窗大小為k,本題解法為建立兩個單調佇列,先從原陣列中取前k個元素按上述要求入隊,然後獲取隊頭元素,再把下一個元素放入隊中,
//再獲取頭元素,這樣一直到最後一個元素為止。最後把答案從頭到尾依次輸出即可。
//
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#define maxn 1000100
using namespace std;


struct node
{
    int val;
    int pos;
};
node minque[maxn],maxque[maxn];
int minans[maxn],maxans[maxn];
int main()
{
int n,k,num;
while(scanf("%d%d",&n,&k)!=EOF)
{
    int minhead=0;int mintail=0;
    int maxhead=0;int maxtail=0;
    for(int i=1;i<=k;i++)
    {
        scanf("%d",&num);
        while((minhead<mintail)&&num<=minque[mintail-1].val) mintail--;
        minque[mintail].val=num;
        minque[mintail].pos=i;
        mintail++;

        while((maxhead<maxtail)&&(num>=maxque[maxtail-1].val)) maxtail--;
        maxque[maxtail].val=num;
        maxque[maxtail].pos=i;
        maxtail++;
    }
    int cur=0;
//    cout<<minhead<<" "<<mintail<<endl;
//    cout<<minque[minhead].val<<" "<<minque[1].val<<endl;

//    cout<<minque[minhead].val<<" "<<maxque[maxhead].val<<endl;
    for(int i=k+1;i<=n;i++)
    {
        minans[cur]=minque[minhead].val;
        maxans[cur]=maxque[maxhead].val;
        cur++;
        scanf("%d",&num);
        while((minhead<mintail)&&(i-minque[minhead].pos)>=k) minhead++;
        while((minhead<mintail)&&minque[mintail-1].val>=num) mintail--;
        minque[mintail].val=num;
        minque[mintail].pos=i;
        mintail++;

        while((maxhead<maxtail)&&(i-maxque[maxhead].pos)>=k) maxhead++;
        while((maxhead<maxtail)&&maxque[maxtail-1].val<=num) maxtail--;
        maxque[maxtail].val=num;
        maxque[maxtail].pos=i;
        maxtail++;
    }
    minans[cur]=minque[minhead].val;
    maxans[cur]=maxque[maxhead].val;
    cur++;
    for(int i=0;i<cur-1;i++)
    {
        cout<<minans[i]<<" ";
    }
    cout<<minans[cur-1]<<endl;
    for(int i=0;i<cur-1;i++)
    {
        cout<<maxans[i]<<" ";
    }
    cout<<maxans[cur-1]<<endl;
}
    return 0;
}