zoukankan      html  css  js  c++  java
  • 洛谷 P1886 滑动窗口(单调队列)

    原题
    本题是一道很经典的单调队列模板题,如果想要O(1)的时间内回答每个窗口,用ST表也可以,但是这道题洛谷上会被卡MLE,所以就来介绍一下单调队列。
    因为是初次尝试,也为了便于理解,所以用数组模拟了单调队列
    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,a[1000005],p[1000005];
    int main()
    {
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
          scanf("%d",&a[i]);
        }
        int head=1,tail=0;//定义单调队列的头指针和尾指针,储存的是数组下标。
        for(int i=1;i<=n;i++)//我们先求最小值,头指针储存最小值下标
        {
          if(head<=tail&&p[head]<i-k+1)//首先我们要先判断队列内的元素在不在滑动窗口内,如果不在,则头指针++
            head++;
          while(head<=tail&&a[p[tail]]>a[i])//如果比队尾元素小的话,就继续往下寻找(tail++),直到找不到
            tail--;
         p[++tail]=i;//加入队尾
         if(i>=k)//保证滑动窗口合法
            printf("%d ",a[p[head]]);
        }
        puts("");
        head=1,tail=0;
         for(int i=1;i<=n;i++)
        {
          while(head<=tail&&p[head]<i-k+1)
            head++;
          while(head<=tail&&a[p[tail]]<a[i])//找最大值同理,只要改变下进入队列的比较符号即可
            tail--;
         p[++tail]=i;
         if(i>=k)
            printf("%d ",a[p[head]]);
        }
    return 0;
    }
    
    
    戒骄戒躁,百炼成钢!
  • 相关阅读:
    Linux基础命令—clear
    Linux基础命令—mv
    Linux基础命令—rm
    Linux基础命令—cp
    Linux基础命令—touch
    Linux基础命令—tree
    C#获取设备话筒主峰值(实时音频输出分贝量)
    C# 获取基类或者接口的所有继承类方法
    RegisterAttached 两种绑定方式
    RijndaelManaged 加密
  • 原文地址:https://www.cnblogs.com/Pecoz/p/12514864.html
Copyright © 2011-2022 走看看