zoukankan      html  css  js  c++  java
  • 【Sliding Window】单调队列

    题目描述

    给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表: 

    你的任务是找出窗口在各位置时的最大值和最小值。

    输入格式

    输入的第 1 行是两个整数 n,k,第 2 行为长度为 n 的数组(即有 n 个整数)。

    输出格式

     输出 2 行,第 1 行是每个位置的最小值,第 2 行是每个位置的最大值。 

    样例数据 1

    输入  [复制]

    8 3 
    1 3 -1 -3 5 3 6 7

    输出

    -1 -3 -3 -3 3 3 
    3 3 5 5 6 7

    备注

    【数据范围】 

    对于 20% 的数据:n<=500;
    对于 50% 的数据:n<=100000;
    对于 100% 的数据:n<=1000000;

    题目分析

    入门级别单调队列。分别维护一个单调递增和单调递减的队列,每次添加新数并维护单调性,然后删除队首的在区间外面的数,最后队首就是答案。

    code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    const int N = 1000005, oo = 0x3f3f3f3f;
    typedef pair<int, int> P;
    int data[N], head, tail, n, k;
    P que[N];
    
    inline int read(){
        int i = 0, f = 1; char ch = getchar();
        for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
        if(ch == '-') f = -1, ch = getchar();
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            i = (i << 3) + (i << 1) + (ch - '0');
        return i * f;
    }
    
    inline void wr(int x){
        if(x < 0) putchar('-'), x = -x;
        if(x > 9) wr(x / 10);
        putchar(x % 10 + '0');
    }
    
    int main(){
        n = read(), k = read();
        for(int i = 1 ; i <= n; i++) data[i] = read();
        tail = head = 1;
        que[head].second = oo;
        for(int i = 1; i <= n; i++){
            if(data[i] < que[head].second)
                que[head = tail = 1] = P(i, data[i]);
            else{
                while(head < tail && que[tail].second > data[i]) tail--;
                que[++tail] = P(i, data[i]);
            }
            while(que[head].first <= i - k) head++;
            if(i >= k)
                wr(que[head].second), putchar(' ');
    //        cout<<endl<<"!!";for(int j = head; j <= tail; j++) cout<<"("<<que[j].first<<") "<<que[j].second<<" ";cout<<endl;
        }
        putchar('
    ');
        tail = head = 1;
        que[head].second = -oo;
        for(int i = 1; i <= n; i++){
            if(data[i] > que[head].second)
                que[head = tail = 1] = P(i, data[i]);
            else{
                while(head < tail && que[tail].second < data[i]) tail--;
                que[++tail] = P(i, data[i]);
            }
            while(que[head].first <= i - k) head++;
            if(i >= k)
                wr(que[head].second), putchar(' ');
        //        cout<<endl<<"!!";for(int j = head; j <= tail; j++) cout<<que[j].first<<" "<<que[j].second<<" ";cout<<endl;
        }
        return 0;
    }

     

  • 相关阅读:
    网络编程
    面向对象总结
    面象对象编程(选课系统)
    类的魔法方法和部分单例模式
    简易3D开发,ThingJS之大道至简
    ThingJS参与3D众创,一起建设“实体中国”!
    ThingJS:轻松让空间“立起来”,展示你的3D创造力
    一个产品的状态不好?ThingJS来找茬
    ThingJS提供有地理位置的信息弹窗示例
    一次灵感盛宴,ThingJS推出场景Market
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7253480.html
Copyright © 2011-2022 走看看