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

    题目描述

    有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

    例如:

    The array is [1,3,-1,-3,5,3,6,7]] and k=3。

    输入格式

    输入一共有两行,第一行有两个正整数 n,k。 第二行 n 个整数,表示序列 a

    输出格式

    输出共两行,第一行为每次窗口滑动的最小值
    第二行为每次窗口滑动的最大值

    输入输出样例

    输入 #1
    8 3
    1 3 -1 -3 5 3 6 7
    输出 #1
    -1 -3 -3 -3 3 3
    3 3 5 5 6 7

    说明/提示

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    int read() {
        int x=0; int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    const int maxn=5e6+100;
    int num[maxn];
    int q[maxn];
    int Max[maxn];
    int Min[maxn];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
        }
        int s=1,e=0;//起点和终点 
        for(int i=1;i<=n;i++){
            while(s<=e&&num[i]>=num[q[e]]) e--;//永无出头之日 
            q[++e]=i;
            while(s<=e&&q[e]-q[s]+1>m) s++;
            Max[i]=num[q[s]];
        }//最大值 
        s=1,e=0;
        for(int i=1;i<=n;i++){
            while(s<=e&&num[i]<=num[q[e]]) e--;
            q[++e]=i;
            while(s<=e&&q[e]-q[s]+1>m) s++;
            Min[i]=num[q[s]];
        }
        for(int i=m;i<=n;i++){
            printf("%d ",Min[i]);
        }
        cout<<endl;
        for(int i=m;i<=n;i++){
            printf("%d ",Max[i]);
        }
    }
  • 相关阅读:
    命名规范
    操作文件和目录
    使用本地shadow socks代理
    发送邮件
    sql参数化
    定义常量
    获取嵌套字典值的方法
    通过字符串调用函数
    用字典优化过长的if 语句
    操作文件和目录
  • 原文地址:https://www.cnblogs.com/lipu123/p/13338101.html
Copyright © 2011-2022 走看看