其他分享
首页 > 其他分享> > [洛谷 1886] 滑动窗口

[洛谷 1886] 滑动窗口

作者:互联网

一道经典的单调队列题目

原题传送门

单调指的是元素的规律呈现为一种单调性,递增,递减,或者自定义1576249-20190816123042323-327652433.png

队列指的是只能从队首和队尾进行操作(所以单调队列也可以用STL的deque实现),但单调队列只需要队首的弹出、队尾的插入和弹出


题目的要求是每连续k个数中的最大值和最小值,以维护最大值为例,对于任意在范围内,且在队列中的数x,y,新进队一个数z,z > x && z > y,那么z从队尾进队,x,y出队

Code:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;
const int maxn = 1000100;

int n, k;
int q[maxn], a[maxn];

void getmin()
{
    int head = 0, tail = 0;
    for (int i = 1; i < k; i++)
    {
        while (head <= tail && a[q[tail]] >= a[i])
            tail--;
        q[++tail] = i;
    }
    for (int i = k; i <= n; i++)
    {
        while (head <= tail && a[q[tail]] >= a[i])
            tail--;
        q[++tail] = i;
        while (q[head] <= i - k)
            head++;
        printf("%d ", a[q[head]]);
    }
}

void getmax()
{
    int head = 0, tail = 0;
    for (int i = 1; i < k; i++)
    {
        while (head <= tail && a[q[tail]] <= a[i])
            tail--;
        q[++tail] = i;
    }
    for (int i = k; i <= n; i++)
    {
        while (head <= tail && a[q[tail]] <= a[i])
            tail--;
        q[++tail] = i;
        while (q[head] <= i - k)
            head++;
        printf("%d ", a[q[head]]);
    }
}

int main()
{
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    getmin();
    printf("\n");
    getmax();
    return 0;
}

标签:洛谷,int,队列,tail,maxn,滑动,1886,include,单调
来源: https://www.cnblogs.com/wyctstf/p/11363161.html