4326: 【基础】滑动窗口(1772)

内存限制:128 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:1 解决:1

题目描述

给定一个长度为 lns="http://www.w3.org/1998/Math/MathML">lns="http://www.w3.org/1998/Math/MathML">106)的数组。有一个大小为 lns="http://www.w3.org/1998/Math/MathML"> 的滑动窗口从数组的最左端移动到最右端。你可以看到窗口中的 lns="http://www.w3.org/1998/Math/MathML"> 个数字。窗口每次向右滑动一个数字的距离。

下面是一个例子:

数组是 [lns="http://www.w3.org/1998/Math/MathML">1 lns="http://www.w3.org/1998/Math/MathML">3 lns="http://www.w3.org/1998/Math/MathML">1 lns="http://www.w3.org/1998/Math/MathML">3 lns="http://www.w3.org/1998/Math/MathML">5 lns="http://www.w3.org/1998/Math/MathML">3 lns="http://www.w3.org/1998/Math/MathML">6 lns="http://www.w3.org/1998/Math/MathML">7], lns="http://www.w3.org/1998/Math/MathML">=3。 

你的任务是得到滑动窗口在每个位置时的最大值和最小值。

输入

输入包括两行。

第一行包括 lns="http://www.w3.org/1998/Math/MathML"> 和 lns="http://www.w3.org/1998/Math/MathML"> ,分别表示数组的长度和窗口的大小。(lns="http://www.w3.org/1998/Math/MathML">

第二行包括 lns="http://www.w3.org/1998/Math/MathML"> 个数字。

输出

输出包括两行。

第一行包括窗口从左至右移动的每个位置的最小值。

第二行包括窗口从左至右移动的每个位置的最大值。

样例输入 复制

8 3
1 3 -1 -3 5 3 6 7

样例输出 复制

-1 -3 -3 -3 3 3
3 3 5 5 6 7

提示

#include <iostream>
#include <cstring>
#include <algorithm>
#include <deque>
using namespace std;

const int N = 1000010;
int a[N];
int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];//读入数据
    deque<int> q;
    for(int i = 1; i <= n; i++)
    {
        while(q.size() && q.back() > a[i]) //新进入窗口的值小于队尾元素,则队尾出队列
            q.pop_back();
        q.push_back(a[i]);//将新进入的元素入队
        if(i - k >= 1 && q.front() == a[i - k])//若队头是否滑出了窗口,队头出队 
            q.pop_front();
        if(i >= k)//当窗口形成,输出队头对应的值
            cout << q.front() <<" ";
    }
    q.clear();
    cout << endl;

    //最大值亦然
    for(int i = 1; i <= n; i++)
    {
        while(q.size() && q.back() < a[i]) q.pop_back();
        q.push_back(a[i]);
        if(i - k >= 1 && a[i - k] == q.front()) q.pop_front(); 
        if(i >= k) cout << q.front() << " ";

    }
}