洛谷P1886 滑动窗口
? 解题记录 ? ? 单调队列 ? ? 洛谷 ?    2018-03-22 10:10:42    475    0    0

题目描述

现在有一堆数字共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

说明

50%的数据,n<=10^5

100%的数据,n<=10^6

本题是单调队列的模板题——长度为k的连续区间最大值。

滑动窗口可以看这篇博客:我是这篇博客

#include<cstdio>
using namespace std;
const int maxn = 1e6 + 5;
int n, a[maxn], q[maxn][2], f = 1, b, k;
void push(int x, int t) {
    while(q[b][1] < t && f <= b) --b;
    q[++b][0] = x, q[b][1] = t;
    if(q[f][0] <= x - k) ++f;
}
void push2(int x, int t) {
    while(q[b][1] > t && f <= b) --b;
    q[++b][0] = x, q[b][1] = t;
    if(q[f][0] <= x - k) ++f;
}
int main() {
    scanf("%d%d", &n, &k);
    for(register int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for(register int i = 1; i < k; ++i) push2(i, a[i]);
    for(register int i = k; i <= n; ++i) 
        push2(i, a[i]), printf("%d ", q[f][1]);
    f = 1, b = 0;
    putchar('\n');
    for(register int i = 1; i < k; ++i) push(i, a[i]);
    for(register int i = k; i <= n; ++i) 
        push(i, a[i]), printf("%d ", q[f][1]);
    return 0;
}


上一篇: TYVJ1305 最大子序和

下一篇: 电子科大爆零记

475 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航