• 洛谷 P2032 扫描 题解


    P2032 扫描

    题目描述

    有一个 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。

    【思路】

    单调队列
    手写单调队列有点双指针的意思
    从第一个开始枚举
    如果队首的数超出了k区间的距离限制就将队尾弹出
    直到队首符合在k区间内的要求
    如果队尾的值比这个要插入的值还小
    那这个队尾是不可能被输出的
    他比我小还比我强!这让我怎么活!所以弹出我吧!

    处理完成之后
    每一个k区间需要输出的值就是他的队首
    因为这是一个递减的区间

    【完整代码】

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    const int Max = 2000006;
    int a[Max];
    int q[Max];
    
    int main()
    {
    	int n,k;
    	scanf("%d%d",&n,&k);
    	for(register int i = 1;i <= n;++ i)
    		scanf("%d",&a[i]);
    	int t = 0,w = 1;
    	for(register int i = 1;i <= n;++ i)
    	{
    		while(t <= w && q[t] + k <= i)t ++;
    		while(t <= w && a[q[w]] < a[i])w--;
    		q[++ w] = i;
    		if(i >= k)
    			cout << a[q[t]] << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux C gcc -lm
    ubuntu 工作区中拖动一个窗体到另一个工作区就卡住回不到桌面了
    ArrayList调用remove方法需要注意的地方
    关于Java中File的renameTo函数
    Java管道流
    NPOI Excel 单元格背景颜色对照表
    Java 简单图片截取
    maven pom.xml 配置 cxf-codegen-plugin 生成web服务客户类型
    ZeroClipboard 简单应用
    PromiseJs
  • 原文地址:https://www.cnblogs.com/acioi/p/11645666.html
Copyright © 2020-2023  润新知