zoukankan      html  css  js  c++  java
  • 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("
    ");
    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 }

    本文为个人随笔,如有不当之处,望各位大佬多多指教.
    若能为各位博友提供小小帮助,不胜荣幸.
  • 相关阅读:
    Axis2、Axis1 以及其他接口的调用方式
    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
    百度、谷歌、雅虎网站地图提交地址
    MyEclipse 死掉,JVM terminated. Exit code=1073807364
    有关Servlet的面试题
    SpringMVC文件的上传与下载实现
    Java API 操作HBase Shell
    Java内存模型与线程(二)线程的实现和线程的调度
    Java内存模型与线程(一)
    ubuntu环境下搭建Hadoop集群中必须需要注意的问题
  • 原文地址:https://www.cnblogs.com/LGJC1314/p/6881854.html
Copyright © 2011-2022 走看看