题目大意

给定一行数,共N个。有一个长度为K的窗口从左向右滑动,窗口中始终有K个数字,窗口每次滑动一个数字。求各个时刻窗口中的最大值和最小值。

题目分析

直接搜索,复杂度为O(n^2)。考虑使用单调队列,单调队列中的元素(或者元素的相关信息)单调递增或者递减。在本题中用一个单调递增的队列A保存当前窗口中值逐渐递增的索引,队列的头部元素为当前窗口中的最小值的索引;用一个单调递减的队列B保存当前窗口中值逐渐递减的索引,队列的头部元素为当前窗口中最大值的索引。 
    窗口每移动到一个新的元素ele时,若新元素大于A中的队尾元素,则入队列,否则,不断弹出队尾的元素,直到队尾元素小于ele,然后入队;若新元素小于B的队尾元素,则入队列,否则,不断弹出队尾元素,直到队尾元素大于ele,然后入队。 
    若窗口移动到的最新元素的index - 队列头元素(队列中存放的是索引) > 窗口长度k,则队列头部后移,以保证队列中的索引位于窗口之内。 
    每个元素最多入栈2次,出栈2次,平摊复杂度为O(n).

    单调队列/栈中存放的一般为序列元素的索引(可能还有其他更多信息),且每次新元素和队尾/栈顶元素比较,若满足单调性质,则入队/入栈;否则,不断弹出队尾/栈顶元素,直到满足单调性质,再入队/入栈。 
    有时可能还需要考虑栈和队列的size(如本题中的窗口)

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX_SIZE 1000005
int gMaxInWindow[MAX_SIZE];
int gMinInWindow[MAX_SIZE];
int gIncQ[MAX_SIZE];
int gDecQ[MAX_SIZE];
int gArray[MAX_SIZE];
int main(){
int n, k;
scanf("%d %d", &n, &k);
int inc_front = 0, inc_tail = -1, dec_front = 0, dec_tail = -1;
int ele;
for (int i = 0; i < n; i++){
scanf("%d", &ele);
gArray[i] = ele; while (inc_tail >= inc_front && gArray[gIncQ[inc_tail]] >= ele){
inc_tail--;
}
inc_tail++;
gIncQ[inc_tail] = i; while (dec_tail >= dec_front && gArray[gDecQ[dec_tail]] <= ele){
dec_tail--;
}
dec_tail++;
gDecQ[dec_tail] = i; if (i - gIncQ[inc_front] >= k){
inc_front++;
}
if (i - gDecQ[dec_front] >= k){
dec_front++;
}
if (i >= k - 1){
gMinInWindow[i - k + 1] = gArray[gIncQ[inc_front]];
gMaxInWindow[i - k + 1] = gArray[gDecQ[dec_front]];
}
}
for (int i = 0; i <= n - k; i++){
printf("%d ", gMinInWindow[i]);
}
printf("\n");
for (int i = 0; i <= n - k; i++){
printf("%d ", gMaxInWindow[i]);
} return 0;
}

poj_2823 单调队列的更多相关文章

  1. BestCoder Round #89 B题---Fxx and game(单调队列)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5945     问题描述 输入描述 输出描述 输入样例 输出样例 题意:中文题,不再赘述: 思路:  B ...

  2. 单调队列 && 斜率优化dp 专题

    首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...

  3. FZU 1914 单调队列

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=1914 题意: 给出一个数列,如果它的前i(1<=i<=n)项和都是正的,那么这个数列是正的,问这个 ...

  4. BZOJ 1047 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 题意:见中文题面 思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小.所以可以考 ...

  5. 【BZOJ3314】 [Usaco2013 Nov]Crowded Cows 单调队列

    第一次写单调队列太垃圾... 左右各扫一遍即可. #include <iostream> #include <cstdio> #include <cstring> ...

  6. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  7. hdu 3401 单调队列优化DP

    Trade Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  8. 【转】单调队列优化DP

    转自 : http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列是一种严格单调的队列,可以单调递增,也可以单调递减.队 ...

  9. hdu3530 单调队列

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

随机推荐

  1. msado.tli

    // Created by Microsoft (R) C/C++ Compiler Version 10.00.40219.01 (d0b01b1b).//// e:\threadpool\mysq ...

  2. android 屏幕上面画线

    作业如下:在android屏幕上面任意画线 package feng.f121.drawline;//本人创建的包名,每人有每人的不同的包 import java.security.PublicKey ...

  3. 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等

    一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 {    public:              公有成员(外部接口)    private:              私有 ...

  4. ASIHTTPRequest 简单使用

    ASIHTTPResquest 框架功能强大,应用非常多. 曾经写过ASIHTTPResquest的导入,如今就看一下基本使用 记一下当中基础的操作: 1.发送同步请求: NSURL * url = ...

  5. 学习XML(添加一个子节点) 摘录

    这里介绍添加XML节点的方法. 首先定义XML文件:(bookstore.xml) <?xml version="1.0" encoding="utf-8" ...

  6. suid/guid用法 suid/guid详细解析

    suid/guid 我们在前面曾经提到过s u i d和g u i d.这种权限位近年来成为一个棘手的问题.很多系统供应商不允许实现这一位,或者即使它被置位,也完全忽略它的存在,因为它会带来安全性风险 ...

  7. 找电影资源最强攻略,知道这些你就牛B了!

    找电影资源最强攻略,知道这些你就牛B了! 电影工厂 2015-07-01 · 分享   点击题目下方环球电影,关注中国顶尖电影微杂志 我们也许没有机会去走遍千山万水,却可以通过电影进入各种各样的角色来 ...

  8. java学习之局部变量以及全局变量

    全局变量 什么是全局变量? 全局变量就好比一个容器或者一个公用的东西一样,就类似外面公共场所的凳子一样,大家都可以使用这个凳子. 和他相反的局部变量是啥子东东呢? 局部变量就是局部的东西,如果全局变量 ...

  9. [debootstrap]制作基于arm平台的debian文件系统

    之前用过的Linux文件系统是直接busybox制作的,而当前使用的是debian的Jessie,看了一些博客后,了解到如果使用debian,那么直接使用debootstrap来构建文件系统即可 -- ...

  10. jquery filter和not

    jQuery filter() 方法 filter() 方法允许您规定一个标准.不匹配这个标准的元素会被从集合中删除,匹配的元素会被返回. 下面的例子返回带有类名 "intro" ...