單調隊列之最大最小成員

 


poj2823_Sliding WindowCrawling in process...

Crawling failed

Time Limit:12000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u       

Description

An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:        
The array is [1 3 -1 -3 5 3 6 7], and k is 3.       
Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position.

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.        

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.        

Sample Input

8 3
1 3 -1 -3 5 3 6 7

 

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

Hint

題意:

       給你一個長度不超過10 6 的數組,有一個長度爲k的滑動窗口從數組的最左邊依次移動到最右邊,找出每次移動後整個窗口裏面的最大值和最小值

解析:

     這是一道典型的單調隊列,先給它用降序排一次,隊列的第一個數就是每次移動後的最大值,同理,升序排一次可以得到最小值。不過這道題有點坑,不能用G++提交,因爲那樣必須超時,但換成C++就能過(李博學長解釋是由於C++用的是WINDOWS的編譯器,對輸入輸出有優化的,但是G++沒有優化。)

 

 

#include<iostream>
#include<cstdio>
using namespace std;

int w[1000006],q[1000006],p[1000006];
int dow[1000006],up[1000006],p1,p2,q1,q2;

int main()
{
    int n,k,minx,i;
    scanf("%d %d",&n,&k);
    p1=p2=q1=q2=1;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&w[i]);
        while(p1<p2&&w[i]<=w[p[p2-1]])//形成一個單調遞增隊列
           p2--;//w[p[p1]]最小
        p[p2++]=i;//入隊
        while(q1<q2&&w[i]>=w[q[q2-1]])//形成一個單調遞減數列,注意是q2-1
            q2--;
        q[q2++]=i;//q2-1的原因
        if(i-p[p1]>=k) p1++;
        if(i-q[q1]>=k) q1++;
        if(i>=k)
        {
            dow[i]=w[p[p1]];
            up[i]=w[q[q1]];
            printf("%d ",dow[i]);
        }
    }
    //for(i=k;i<n;i++)
       // printf("%d ",dow[i]);
    printf("\n");
    for(i=k;i<n;i++)
        printf("%d ",up[i]);
    printf("%d\n",up[i]);
    return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章