• 单调队列 洛谷P1886 滑动窗口


    题目链接:https://www.luogu.org/problem/P1886

    题意:给一串一维数字序列,并给你一个长为k的小框,从左到右一格格滑过去,求每次小框内的最大值最小值分别为多少。

    据说是单调队列模板题。讲解洛谷排第一的题解就讲的很好。

    简略说就是维护一个单调的队列(增或减)每次移到新的一格就会把队尾和当前做比较,不满足单调性就一直去掉队尾,一直到满足为止,因为有单调性,队首就是答案。除了队列q数组,还有一个p数组,用来放队内元素在原序列中的下标。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=1<<30;
    const int maxn=1e6+7;
    int a[maxn],p[maxn],q[maxn];
    int n,k;
    void ask_min(){
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        int tail=1,head=0;
        for(int i=1;i<=n;i++){
            while(head<=tail&&q[tail]>=a[i])tail--;
            q[++tail]=a[i];p[tail]=i;
            while(p[head]<=i-k)head++;
            if(i>=k)printf("%d ",q[head]);
        }
    }
    void ask_max(){
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        int tail=1,head=0;
        for(int i=1;i<=n;i++){
            while(head<=tail&&q[tail]<=a[i])tail--;
            q[++tail]=a[i];p[tail]=i;
            while(p[head]<=i-k)head++;
            if(i>=k)printf("%d ",q[head]);
        }
    }
    int main(){
        cin>>n>>k;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        ask_min();cout<<endl;
        ask_max();cout<<endl;
        return 0;
     }
  • 相关阅读:
    1 3
    linux常用命令
    linux的目录结构
    linux的shell编程
    linux的IP配置
    linux安装
    linux简介
    ubuntu16.04上系统管理服务和配置
    PXE
    RPC框架原理
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11336194.html
Copyright © 2020-2023  润新知