POJ--2823--Sliding Window----单调队列问题

Posted 太子丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ--2823--Sliding Window----单调队列问题相关的知识,希望对你有一定的参考价值。

Sliding Window

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 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
題意 :
  给定一个数字序列,与每次所能看见的序列长度m即窗户长度,从左向右依次移动窗户,输出每次所能看到的序列长度的最大值与最小值,直到序列结束.
思路:
  以求最小值为例,
  1.构造递增的单调队列,即队尾元素需要小于当前元素,否则队尾元素出队.
  2.首先,将前 m-1 个元素按照单调队列原则进队,并记录队列中的每个元素在数组中的下标;
   其次,将剩余的元素依次进队,以 第i元素为例子,将第i元素与队尾比较,若是小于队尾,则队尾出队,否则当前元素进队,此时队列是单调递增有序的,
   再之,将队头元素的下标与当前元素的下标比较,若 当前元素下标 - 队头元素下标<=m-1,则队头元素便为最小值,否则队头出队.
  3.将剩余元素依次进行步骤2,便得到所求的所有最小值,求最大值亦然.
AC代码分析 (请用C++提交,否则Time Limit Exceeded):
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <vector>
 7 #include <map>
 8 #include<string.h>
 9 #include<stack>
10 #include<set>
11 #include <queue>
12 using namespace std;
13 int a[1000005];
14 //队列中各元素的下标
15 int p[1000005];
16 //各个区间的最大值
17 int max1[1000005];
18 //各个区间的最小值
19 int min1[1000005];
20 //数组模拟递增队列
21 int qmax[1000005];
22 //数组模拟递减队列
23 int qmin[1000005];
24 //队头,队尾
25 int head,tail;
26 int main()
27 {
28     int n,m,i,t;
29     while(~scanf("%d%d",&n,&m))
30     {
31         for( i = 1; i<=n; i++) scanf("%d",a+i);
32         //队头队尾初始化
33         head = 1;
34         tail = 0;
35         t = 1;
36         //前m-1个元素进队列
37         for( i = 1; i<=m-1; i++)
38         {
39             while(head<=tail&&qmin[tail]>=a[i]) tail--;
40             qmin[++tail] = a[i];
41             //队列中各元素的下标
42             p[tail] = i;
43 
44         }
45         //求所有的最小值
46         for(; i<=n; i++)
47         {
48             //进队
49             while(head<=tail&&qmin[tail]>=a[i]) tail--;
50             qmin[++tail] = a[i];
51             p[tail] = i;
52             //判断对头是否在当前范围内
53             while(i-p[head]>m-1)
54                 head++;
55             min1[t++] = qmin[head];
56         }
57         head = 1;
58         tail = 0;
59         t = 1;
60         //求所有的最大值
61         for( i = 1; i<=m-1; i++)
62         {
63             while(head<=tail&&qmax[tail]<=a[i]) tail--;
64             qmax[++tail] = a[i];
65             p[tail] = i;
66         }
67         for(; i<=n; i++)
68         {
69             //进队
70             while(head<=tail&&qmax[tail]<=a[i]) tail--;
71             qmax[++tail] = a[i];
72             p[tail] = i;
73             //判断对头是否在当前范围内
74             while(i-p[head]>m-1)
75                 head++;
76             max1[t++] = qmax[head];
77         }
78         for( i = 1; i<t; i++)
79         {
80             if(i == 1)
81                 printf("%d",min1[i]);
82             else
83                 printf(" %d",min1[i]);
84         }
85         printf("\n");
86         for( i = 1; i<t; i++)
87         {
88             if(i == 1)
89                 printf("%d",max1[i]);
90             else
91                 printf(" %d",max1[i]);
92         }
93 
94     }
95     return 0;
96 }

 


本文为个人随笔,如有不当之处,望各位大佬多多指教.
若能为各位博友提供小小帮助,不胜荣幸.

以上是关于POJ--2823--Sliding Window----单调队列问题的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2823 Sliding Window

POJ 2823 Sliding Window

POJ2823 Sliding Window

poj 2823 Sliding Window 题解

POJ#2823. Sliding Window

poj 2823 Sliding Window