zoukankan      html  css  js  c++  java
  • 单调队列——POJ

    题目含义

    给出一个区间的长度,要你在一堆数中移动这个区间(保持区间长度不变),找出对应的最大最小值 

    题目解析

    这个区间在向右移动,那么时时刻刻有数离开这个区间,有数加入这个区间,这样的话可以考虑单调队列

    把这些数按从大到小的顺序放入一个数组,并且从大到小判断这个数是否满足在这个区间,不满足就取出

    这样队列头就是这个区间的最大值,同理最小

    题目代码

    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    const int maxn=1e6+7;
    int n,k,h,t;
    int a[maxn],q[maxn],maxx[maxn],minn[maxn];
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        h=1,t=0;
        for(int i=1;i<=n;i++){
            while(h<=t&&a[q[t]]<=a[i])t--;///满足单调数组单调递减的性质
            q[++t]=i;
            while(i-k>=q[h])h++;///判断此时的最大值a[q[h]]的下标在不在区间内
            maxx[i]=a[q[h]];
        }
        h=1,t=0;
        for(int i=1;i<=n;i++){
            while(h<=t&&a[q[t]]>=a[i])t--;///单调递增的数组
            q[++t]=i;
            while(i-k>=q[h])h++;
            minn[i]=a[q[h]];
        }
        if(k>=n){
            printf("%d
    %d
    ",minn[n],maxx[n]);
        }
        else{
            for(int Qi=k;i<n;i++)
                printf("%d ",minn[i]);
            printf("%d
    ",minn[n]);
            for(int i=k;i<n;i++)
                printf("%d ",maxx[i]);
            printf("%d
    ",maxx[n]);
        }
        return 0;
    }
    

     挺简单的,本来以为能一次过的,结果又忘了算完最大值后要重置h和t

  • 相关阅读:
    js 置顶操作
    js input输入数量控制
    js 时间倒计时
    html内容垂直居中
    大图片随浏览器水平居中显示
    img,display:inline相关间隙样式问题
    js淡入淡出轮换思想(1)
    js 禁止|阻止滚动条滚动
    kotlin学习--第一个kotlin项目
    jdk8+Mybatis3.5.0+Mysql读取LongBlob失败
  • 原文地址:https://www.cnblogs.com/helman/p/11222221.html
Copyright © 2011-2022 走看看