洛谷 P1886 滑动窗口 /【模板】单调队列

洛谷 P1886 滑动窗口 /【模板】单调队列 

用数组que模拟双端队列(前后都可踢出元素)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1e6 + 5;

int n, k;
int a[maxN];
int que[maxN], id[maxN];
int head, rear;

void init()
{
    head = 1;
    rear = 0;
}

int main()
{
    while(~scanf("%d%d", &n, &k))
    {
        for(int i = 1; i <= n; i ++ )
            scanf("%d", &a[i]);
        //找区间最小值
        init();
        for(int i = 1; i <= n; i ++ )
        {
            while(head <= rear && que[rear] > a[i])//找到第一个小于a[i]的值的下标,如果没有就是head
                -- rear ;
            que[ ++ rear] = a[i];
            id[rear] = i;
            if(id[head] <= i - k)//保证最小元素是在长度范围内的也就是[i - len + 1, i]中的元素
                head ++;
            if(i >= k)//区间长度足够时就可以输出了。
                printf("%d ", que[head]);
        }
        putchar('\n');
        //找区间最大值
        init();
        for(int i = 1; i <= n; i ++ )
        {
            while(head <= rear && que[rear] < a[i])//找到第一个大于a[i]的值的下标,如果没有就是head
                -- rear ;
            que[ ++ rear] = a[i];
            id[rear] = i;
            if(id[head] <= i - k)
                head ++;
            if(i >= k)
                printf("%d ", que[head]);
        }
        putchar('\n');
    }
    return 0;
}
/*
7 3
7 8 -1 12 6 7 11
 */
发布了180 篇原创文章 · 获赞 54 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/103937223