• 单调队列


     
     

    题目描述

    有一个 1 ∗ n 的矩阵,有 n 个正整数。

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

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

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

    输入输出格式

    输入格式:

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

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

    输出格式:

    共 n − k + 1 行,每行一个正整数。

    第 i 行表示第 i ∼ i + k − 1 个数中最大值是多少。

    输入输出样例

    输入样例#1:
    5 3
    1 5 3 4 2
    输出样例#1: 
    5
    5
    4

    说明

    对于 20% 的数据保证:1 ≤ n ≤ 1e3,1 ≤ k ≤ n

    对于 50% 的数据保证:1 ≤ n ≤ 1e4,1 ≤ k ≤ n

    对于 100% 的数据保证:1 ≤ n ≤ 2 ∗ 1e6,1 ≤ k ≤ n

    矩阵中元素大小不超过 1e4。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=2e6+10;
     4 int a[N],n,k,tot,q[N],head;
     5 int main() {
     6     scanf("%d%d", &n, &k);
     7     for (int i = 1; i <= n; i++) {
     8         scanf("%d", &a[i]);
     9     }
    10     head = tot = 1;
    11     q[1] = 1;
    12     for (int i = 1; i <= n; i++) {
    13         if (q[head] <= i - k) {
    14             head++;
    15         }
    16         while (tot >= head && a[q[tot]] <= a[i]) {
    17             tot--;
    18         }
    19         q[++tot] = i;
    20         if (i >= k) {
    21             printf("%d
    ", a[q[head]]);
    22         }
    23     }
    24 }
    View Code

    思路:

    实际上就是单调队列的直接应用。以维护每个滑动窗口的最大值为例
    • 维护一个下标和元素值都单调递增的队列
    • 每次滑动窗口往后移动新增一个元素,当前队列队尾比它还大的元素显然是没用的,可以直接删掉。这样队列中保存的都是“有用”
    的东西
    • 当队头的元素超出了窗口的范围,就要删掉
    • 这么一番操作后,数据结构的性质没有发生变化
    • 答案就是队头元素的值
  • 相关阅读:
    一百一十五:CMS系统之实现点击更换图形验证码功能
    python用cx_Oracle连接oracle
    一百一十四:CMS系统之图形验证码生成
    一百一十三:CMS系统之前台注册界面
    一百一十二:CMS系统之前台用户模型
    一百一十一:CMS系统之后端权限验证功能
    前端开发之JavaScript HTML DOM理论篇二
    前端开发之JavaScript HTML DOM理论篇一
    前端开发之JavaScript基础篇四
    前端开发之JavaScript基础篇三
  • 原文地址:https://www.cnblogs.com/Accpted/p/11211330.html
Copyright © 2020-2023  润新知