POJ2823 滑动窗口

滑动最小(最大)值,模版题。

题意:给一个数列,给一个窗口大小k,顺序求每个窗口中最大值和最小值。

和挑战中的例题一模一样,就多了一个求最大,改个大于小于符号就行。

算法是利用双端队列:

以求最小值为例,维护这样一个队列:

1.队列中元素保存数列下标,数列中元素(下标)递增,并且下标对应数列中元素(下标对应值)也递增。

显然我们i从0开始遍历保证了队列中保存的下标是递增的,我们只需要设计算法保证下标对应数列中元素也递增即可。

2.加入一个下标时,从后往前删掉所有对应值大于当前下标对应值的下标,使得下标对应元素也能递增。

3.将这个下标加入队列

4.如果队列首位元素在后面不再需要用到了,队列首位后移一位。

举例

n=5

k=3

a={1,3,5,4,2}

 

加入0 -> {0}

加入1 -> {0,1}

加入2 -> {0,1,2}

当前窗口最小值=a0=1

删除0 -> {1,2}

 

加入3 -> {1,3} (a2>=a3,删除2)

当前窗口最小值=a1=3

删除1 -> {3}

 

加入4 -> {4} (a3>=a4,删除3)

当前窗口最小值=a4=2

 

Description

An array of size n ≤ 106 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 positionMinimum valueMaximum 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
 1 #include<iostream>
 2 #include <cstdio>
 3 #define MAX_N 1000000 + 16
 4 
 5 using namespace std;
 6 int x[MAX_N];
 7 int b[MAX_N],c[MAX_N];
 8 int que[MAX_N];
 9 int l,r;
10 int main(int argc, char *argv[])
11 {
12     int n,k;
13     cin >> n >> k;
14     for(int i=0; i<n; i++)
15         cin >> x[i];
16     l=r=0;
17     for(int i=0; i<n; i++)
18     {
19         while(l<r&&x[que[r-1]]>=x[i] )r--;
20         que[r++]=i;
21 
22         if(i-k+1>=0)
23         {
24             b[i-k+1]=x[que[l]];
25 
26             if(que[l]==i-k+1)
27             {
28                 l++;
29             }
30         }
31     }
32     l=r=0;
33     for(int i=0; i<n; i++)
34     {
35         while(l<r&&x[que[r-1]]<=x[i] )r--;
36         que[r++]=i;
37 
38         if(i-k+1>=0)
39         {
40             c[i-k+1]=x[que[l]];
41 
42             if(que[l]==i-k+1)
43             {
44                 l++;
45             }
46         }
47     }
48     for(int i=0; i<=n-k; i++)
49         printf("%d%c",b[i],i==n-k?'\n':' ');
50     for(int i=0; i<=n-k; i++)
51         printf("%d%c",c[i],i==n-k?'\n':' ');
52     return 0;
53 }
View Code

 

posted on 2018-05-03 21:41  Best_Efforts  阅读(207)  评论(0编辑  收藏  举报

导航