• WHYZOJ-#47. 滑行的窗口(单调队列)


    【题目描述】:

    给定一个长度为n的数列a,再给定一个长度为k的滑动窗口,从第一个数字开始依次框定k个数字,求每次框定的数字中的最大值和最小值,依次输出所有的这些值。下面有一个例子数组是 [1 3 1 3 5 6 7] , k 是3:

           窗口位置              窗口中的最小值   窗口中的最大值
    [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

    【输入描述】:

    第一行包含两个整数 n 和 k ,分别表示数组的长度和滑动窗口长度。

    第二行n个整数,表示数列元素的值。

    【输出描述】:

    第一行从左到右窗口看到的最小值。

    第二行从左到右窗口看到的最大值。

    【样例输入】:

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

    【样例输出】:

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

    【时间限制、数据范围及描述】:

    时间:1s 空间:64M

    30%:n<=100 k<=20

    60%:n<=5000 k<=20

    100%:n<=10^6,每个元素不操过int类型

    需要读入输出优化

    二十分钟敲完……手速还算可以:( 不过今天也就这样了;(

     1 #include "bits/stdc++.h"
     2 using namespace std;
     3 typedef long long LL;
     4 const int MAX=1000005;
     5 int n,m;
     6 int a[MAX];
     7 struct Que{
     8     int na;
     9     int sco;
    10 }q[MAX];
    11 inline int read(){
    12     int an=0,x=1;char c=getchar();
    13     while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
    14     while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();}
    15     return an*x;
    16 }
    17 void getmin(){
    18     int i,j;
    19     int head=1,tail=0;
    20     for (i=1;i<=n;i++){
    21         while (head<=tail && i-q[head].na>=m) head++;
    22         while (head<=tail && a[i]<q[tail].sco) tail--;
    23         q[++tail].sco=a[i];q[tail].na=i;
    24         if (i>=m){
    25             printf("%d ",q[head].sco);
    26         }
    27     }
    28     printf("
    ");
    29 }
    30 void getmax(){
    31     int i,j;
    32     int head=1,tail=0;
    33     for (i=1;i<=n;i++){
    34         while (head<=tail && i-q[head].na>=m) head++;
    35         while (head<=tail && a[i]>q[tail].sco) tail--;
    36         q[++tail].sco=a[i];q[tail].na=i;
    37         if (i>=m){
    38             printf("%d ",q[head].sco);
    39         }
    40     }
    41     printf("
    ");
    42 }
    43 int main(){
    44     freopen ("window.in","r",stdin);
    45     freopen ("window.out","w",stdout);
    46     int i,j;
    47     n=read();m=read();
    48     for (i=1;i<=n;i++){
    49         a[i]=read();
    50     }
    51     getmin();
    52     getmax();
    53     return 0;
    54 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    Linux CAT与ECHO命令详解
    查看linux版本信息
    kubernetes(一)
    Chrome不安装插件实现页面长截图
    centos 升级glibc-2.17
    redis修改大key报Argument list too long的解决办法
    mysql打印用户权限的小技巧
    Centos6.5 自带的Python2.6.6 如何安装setuptools和pip
    TCP三次握手过程中涉及的队列知识的学习
    Docker volume权限导致的几个问题
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/7555058.html
Copyright © 2020-2023  润新知