[洛谷 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