• 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]);
        }
    }
  • 相关阅读:
    windows 环境下 eclipse + maven + tomcat 的 hello world 创建和部署
    使用IntelliJ IDEA 14和Maven创建java web项目
    使用Spring JDBCTemplate简化JDBC的操作
    CSS颜色代码 颜色值 颜色名字大全
    mysql创建数据库命令
    win64位安装python-mysqldb1.2.3
    UVA11426 欧拉函数
    关于gcd的几个问题
    POI2007_zap 莫比乌斯反演
    BZOJ2005 莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/lipu123/p/13338101.html
Copyright © 2020-2023  润新知