单调队列C++

单调队列

一、概念

单调队列是指:队列中元素之间的关系具有单调性,而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。

单调队列顾名思义就是一个有规律的队列,这个队列的规律是:所有在队列里的数都必须按递增(或递减)的顺序列队。

例如:

有如下一串数字:1 5 3 4 2
首先第一个数字1先进队列,que = {1};
之后第二个数字5大于1,则1出队列5进队列,que = {5};
下一步第三个数字3小于5,进队列,que = {5,3};
下一步第四个数字4大于3,则3出队列4进队列,que = {5,4};
下一步第五个数字2小于4,进队列,que = {5,4,2};
这样最后队列里的数字为单调递减排列。

二、模板:

//que数组存储数据在a数组中的下标
que[++tail] = 1;//第一个数据先进入队列
for(int i = 2; i <= n; i++){
       while(head<= tail && i - que[head] == k)//判断最大的数是否在范围之内,若不在则出队列
              head++;
       while(head<= tail && a[i] >= a[que[tail]])//当新插入的数比队尾大时,弹出队尾的数
              tail--;
       que[++tail]= i; //新插入的数进入队列
       if(i>= k)
              printf("%d\n",a[que[head]]);
       }

三、例题:

题目描述

有一个 1 x n 的矩阵,有n个整数。
现在给你一个可以盖住连续k个数的木板。
一开始木板盖住了矩阵的第i~k 个数,每次将木板向右移动一个单位,直到右端与第n个数重合。
每次移动前输出被覆盖住的数字中最大的数是多少。

输入格式

第一行两个整数n,k,表示共有 n 个数,木板可以盖住 k 个数。
第二行n个整数,表示矩阵中的元素。

输出格式

共 n - k + 1行,每行一个整数。
第i行表示第 i ~i + k - 1个数中最大值是多少。

样例输入

5 3
1 5 3 4 2

样例输出

5     5     4

AC代码;

#include<stdio.h>
#define maxn 2000001
int head = 1, tail = 0;
int a[maxn], que[maxn];
 
int main(){
       int n,k;
       scanf("%d%d", &n, &k);
       for(inti = 1; i <= n; i++){
              scanf("%d",&a[i]);
       }
       //单调队列递减,则队头为最大元素
       que[++tail]= 1;
       for(inti = 2; i <= n; i++){
              while(head<= tail && i - que[head] == k)//判断最大的数是否在范围之内,若不在则出队列
                     head++;
              while(head<= tail && a[i] >= a[que[tail]])//当新插入的数比队尾大时,弹出队尾的数
                     tail--;
              que[++tail]= i; //新插入的数进入队列
              if(i>= k)
                  printf("%d\n", a[que[head]]);
       }
       return0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值