[luogu p2032] 扫描

传送门

扫描

题目描述

有一个 \(1 \times n\) 的矩阵,有 \(n\) 个整数。

现在给你一个可以盖住连续 \(k\) 个数的木板。

一开始木板盖住了矩阵的第 \(1 \sim k\) 个数,每次将木板向右移动一个单位,直到右端与第 \(n\) 个数重合。

每次移动前输出被覆盖住的数字中最大的数是多少。

输入输出格式

输入格式

第一行两个整数 \(n,k\),表示共有 \(n\) 个数,木板可以盖住 \(k\) 个数。

第二行 \(n\) 个整数,表示矩阵中的元素。

输出格式

\(n - k + 1\) 行,每行一个整数。

\(i\) 行表示第 \(i \sim i + k - 1\) 个数中最大值是多少。

输入输出样例

输入样例 #1

5 3
1 5 3 4 2

输出样例 #1

5
5
4

说明

对于 \(20\%\) 的数据,\(1 \leq k \leq n \leq 10^3\)

对于 \(50\%\) 的数据,\(1 \leq k \leq n \leq 10^4\)

对于 \(100\%\) 的数据,\(1 \leq k \leq n \leq 2 \times 10^6\),矩阵中的元素大小不超过 \(10^4\) 并且均为正整数。

分析

暴力做法很容易想到 \(\mathcal{O}(nk)\) 做法。但是这个做法实在是太暴力了,我们需要换单调队列做。

定义一个双向队列 \(q\) 作为单调队列,其中 \(q\) 中每一个元素包含两个变量:元素的数值和元素的位置

为什么要保存元素的位置呢?因为我们得实时监测当前的最大值所对应的位置是否还在当前的窗口。

对于每一个元素,进行入队操作(同时也要维护这个单调队列),并检查当前单调队列的队首(最大值)的位置是否还在这个窗口,如果没在,我们需要弹出。然后输出当前队首的值即可。(单调队列的队首就是最大值了)。

这种方法的时间复杂度是 \(\mathcal{O}(n)\),可以说十分优秀了。

核心代码如下:

    for (int i = 1; i <= n; ++i) {
        while (!q.empty() && q.back().first <= a[i])
            q.pop_back();
        q.push_back(std :: make_pair(a[i], i));
        if (q.front().second == i - k)
            q.pop_front();
        if (i >= k)
            std :: printf("%d\n", q.front().first);
    }

整体code如下:

代码

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2020-10-17 19:04:13 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2020-10-17 20:28:32
 */
#include <iostream>
#include <cstdio>
#include <utility>
#include <deque>
#include <functional>

typedef std :: pair<int, int> Pair;

std :: deque <Pair> q;

const int maxn = 2000005;
int a[maxn];

int main() {
    int n, k;
    std :: scanf("%d %d", &n, &k);
    for (int i = 1; i <= n; ++i)
        std :: scanf("%d", &a[i]);
    
    for (int i = 1; i <= n; ++i) {
        while (!q.empty() && q.back().first <= a[i])
            q.pop_back();
        q.push_back(std :: make_pair(a[i], i));
        if (q.front().second == i - k)
            q.pop_front();
        if (i >= k)
            std :: printf("%d\n", q.front().first);
    }

    return 0;
}

评测记录

评测记录

posted @ 2020-10-18 18:05  dbxxx  阅读(168)  评论(0编辑  收藏  举报