• 单调队列


    单调队列

    性质

    单调队列和单调栈很像,就是一个维护了单调性的队列数据结构,可以是单调递增的,也可以是单调递减的。

    模型

    下图是一个单调递增的单调队列模型。

    其中元素也是从小到大排列。
    和单调栈的操作一样,如果加入一个满足单调性的元素,例如5,那么就直接加入。

    那么如果加入一个元素3呢?我们维护单调性,需要把队列尾端把大于3的元素全部弹出,那么就需要用双端队列来实现了,当然操作和单调栈是一样的。

    单调队列有许多作用:

    比如可以求出一个数组内第一个大于等于一个数x的数

    也可以通过维护单调性,解决一些区间内最小或最大的问题

    总之单调队列的应用在根本上要视题目而定的灵活运用

    本质上并不复杂

    如果求最大,就维护单调递减的队列;如果求最小,就维护单调递增的队列

    题目描述

    现在有一堆数字共N个数字(N<=10^6),以及一个大小为k

    的窗口。现在这个从左边开始向右滑动,每次滑动一个单

    位,求出每次滑动后窗口中的最大值和最小值。

    例如:

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

    输入格式:

    输入一共有两行,第一行为n,k。

    第二行为n个数(<INT_MAX).

    输出格式:

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

    第二行为每次窗口滑动的最大值

    输入输出样例

    输入样例#1:

    8 3

    1 3 -1 -3 5 3 6 7

    输出样例#1:

    -1 -3 -3 -3 3 3

    3 3 5 5 6 7

    请用C++提交

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    
    #define INF 0x3f3f3f3f
    #define LL long long
    #define MAXN 2000005
    using namespace std;
    
    struct Node{
        int index;
        int val;
    };
    
    int a[MAXN];
    deque<Node> q;
    
    int main()
    {
        int n,m;
        Node node;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for (int i=1;i<=n;i++)     // 区间最大值
        {
            node.val = a[i];
            node.index = i;
            while (!q.empty() && q.back().val<a[i])
                q.pop_back();
            q.push_back(node);
            if (i>=m)
            {
                while (!q.empty() && q.front().index+m<=i)
                    q.pop_front();
                printf("%d
    ",q.front().val);
            }
        }
        while (!q.empty())    //区间最小值
            q.pop_front();
        for (int i=1;i<=n;i++)
        {
            node.val = a[i];
            node.index = i;
            while (!q.empty() && a[i]<q.back().val)
                q.pop_back();
            q.push_back(node);
            if (i>=m)
            {
                if (!q.empty() && q.front().index+m<=i)
                    q.pop_front();
                printf("%d
    ",q.front().val);
            }
        }
        return 0;
    }
  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11276929.html
Copyright © 2020-2023  润新知