• 洛谷 P1886 滑动窗口(单调队列)


    嗯...

     

    题目链接:https://www.luogu.org/problem/P1886

    首先这道题很典型,是标准的单调队列的模板题(也有人说单调队列只能解决这一个问题)。这道题可以手写一个队列,也可以用STL中的双端队列...

    核心思路:如果一个人比你强并且比你小,那么你无法超过他...

    我们把区间最大值和最小值分开求,下面讲解最大值,最小值则反之:

    如果队列中有元素并且这个元素比要插入的元素大,即这个人比你强还比你小,那么你永远不能比他强,所以就让你出队,然后让那个人入队。接着处理“退役”的人,如果这个人虽然曾在队列中,但是不在现在的窗口中,那么也把它从队首弹出。

    最后注意初始化队列为空和输出...

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 
     4 using namespace std;
     5 const int maxn = 1e6 + 5;
     6 int n, k, head, tail, a[maxn];
     7 
     8 struct node{
     9     int id, val;
    10 } q[maxn];
    11 
    12 inline void work_min(){
    13     head = 1; tail = 0;
    14     for(int i = 1; i <= n; i++){
    15         while(head <= tail && a[i] <= q[tail].val) tail--;
    16         q[++tail].id = i;
    17         q[tail].val = a[i];
    18         while(q[head].id <= i - k) head++;
    19         if(i >= k) printf("%d ", q[head].val);
    20     }
    21     printf("
    ");
    22 }
    23 
    24 inline void work_max(){
    25     head = 1; tail = 0;//初始化 
    26     for(int i = 1; i <= n; i++){
    27         while(head <= tail && a[i] >= q[tail].val) tail--;//比你小比你强 
    28         q[++tail].id = i;
    29         q[tail].val = a[i];
    30         while(q[head].id <= i - k) head++;//退役 
    31         if(i >= k) printf("%d ", q[head].val);//输出 
    32     }
    33     printf("
    ");
    34 }
    35 
    36 int main(){
    37     scanf("%d%d", &n, &k);
    38     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    39     work_min();
    40     work_max();
    41     return 0;
    42 }
    AC代码
  • 相关阅读:
    固定长度下随文字数量增加自动适配字体大小
    vue v-for 和 v-if 、v-else一起使用造成的bug
    火狐使用Ctrl新开窗口不生效
    js如何模拟multipart/form-data类型的请求
    centos安装nodejs
    cursor图标自定义
    解决 vs code 打开文件总是只有一个tab标签页,新打开的tab标签页会替换掉旧的tab标签页
    Devexpress Tab Control 文档
    Devexpress WPF教程
    Linq把一个DataTable根据一列去除重复数据
  • 原文地址:https://www.cnblogs.com/New-ljx/p/11290772.html
Copyright © 2020-2023  润新知