zoukankan      html  css  js  c++  java
  • 单调队列--P1886 滑动窗口 /【模板】单调队列

    *传送

    **单调队列的模板题(做很多题的前置准备)

    本题我们维护一个从大到小/从小到大的单调队列即可。拿最大值来举例:对于新加进来的数,如果比队尾小我们就加进来,否则为了维护单调性我们从队尾弹出比当前值小的值。不难证明这些弹出的值不会是任何一个滑动窗口的答案。对于窗口的限定长度,我们只需要每次判断队首元素所在位置是否超过窗口长度,超过弹出即可,后输出队首(即当前队列中的最大值)即可。

    代码如下:(感觉还是挺简洁易懂的)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 int q1[1000005],q2[1000005];
     7 int n,k,a[1000005];
     8 void maxx(){
     9     int head=1,t=0;
    10     for (int i = 1;i <= n;i++){
    11         while(head<=t&&q1[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出 
    12         while(head<=t&&a[i]>a[q1[t]]) t--;//维护单调性 
    13         q1[++t]=i;
    14         if (i>=k) cout<<a[q1[head]]<<" ";
    15     }
    16 }
    17 void minn(){
    18     int head=1,t=0;
    19     for (int i = 1;i <= n;i++){
    20         while(head<=t&&q2[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出 
    21         while(head<=t&&a[i]<a[q2[t]]) t--;//维护单调性 
    22         q2[++t]=i;
    23         if (i>=k) cout<<a[q2[head]]<<" ";
    24     }
    25 }
    26 int main(){
    27     scanf ("%d%d",&n,&k);
    28     for (int i = 1;i <= n;i++) scanf ("%d",&a[i]);
    29     minn();
    30     cout<<endl;
    31     maxx();
    32     return 0;
    33 }
  • 相关阅读:
    宿主机无法访问CentOS7上Jenkins服务的解决办法
    415. Add Strings
    367. Valid Perfect Square
    326. Power of Three
    258. Add Digits
    231. Power of Two
    204. Count Primes
    202. Happy Number
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12487340.html
Copyright © 2011-2022 走看看