【Codevs】3339 扫描 单调队列

来源:互联网 发布:java人机猜拳源代码 编辑:程序博客网 时间:2024/06/07 01:11

题面–>

题目描述 Description

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

输入描述 Input Description

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

输出描述 Output Description

共 n-k+1 行

样例输入 Sample Input

5 31 5 3 4 2

样例输出 Sample Output

554

分析–>

单调递减队列。
从后面入队时,如果队尾元素 比 当前进入的 x 小,删除这个元素,直到删到 比 x 大。
如果 目前在单调队列的队首元素 已经不在 k 的覆盖范围内了, 就删去。

代码–>

#include <iostream>#include <queue>#include <cstring>#include <cstdio>using namespace std;int n, k;struct haha{    int v, p;};deque<haha> q;void push(int x, int p){    while(!q.empty() && q.back().v <= x)        q.pop_back();    q.push_back((haha){x,p});}int main(){    int x;    scanf("%d%d",&n,&k);    for(int i = 1; i <= n; i ++)    {        scanf("%d",&x);        push(x,i);        if(i >= k){            while(q.front().p <= (i - k))                q.pop_front();            printf("%d\n",q.front());        }           }    return 0;}
1 0
原创粉丝点击