【POJ 2823 Sliding Window】 单调队列
题目大意:给n个数,一个长度为k(k<n)的闭区间从0滑动到n,求滑动中区间的最大值序列和最小值序列。
最大值和最小值是类似的,在此以最大值为例分析。
数据结构要求:能保存最多k个元素,快速取得最大值,更新时删去“过期”元素和“不再有希望”的元素,安放新元素。
单调队列的基本概念百度百科讲得比较清楚了:http://baike.baidu.com/view/3771451.htm
我的大致思路是:
1. 每个元素存储为结构体,包含它的秩和值。维护最大长度为k的单调队列,保证所有元素的秩都在区间内,且从首到尾的元素,秩递增,值递减。
2. 读入前k个元素(不存在过期问题),安放每个元素c:从队尾开始往回找到第一个大于它的元素g,将c放到g后面,c成为新的队尾
3. 队首赋给最大值序列的第一个值。
4. 读入k~n-1的元素,每读入一个元素c:
(1)处理队首的过期元素(每次最多只可能是队首一个元素过期,因为队列长度不超过k,且秩是单调增的)
(2)安放c(方法同前k个元素)
(3)将新队首赋给最大值序列的下一个值
5. 输出最大值序列
想清楚了的话,代码还是比较好写的;队列没有封装,简单地用数组+首尾指针实现:
#include <cstdio>
#include <cstring>
using namespace std; struct Node
{
int index;
int value;
}; Node max_q[],min_q[];
int max_res[],min_res[];
int front_max,front_min;//队首指针
int back_max,back_min;//队尾指针
int n,k,c; int main()
{
//freopen("c.txt","r",stdin);
scanf("%d%d",&n,&k);
back_max=back_min=front_max=front_min=;
scanf("%d",&c);
max_q[back_max].value=c;
min_q[back_min].value=c;
max_q[back_max].index=;
min_q[back_min].index=;//用第一个元素初始化
for(int j=;j<k;j++)//前k个元素
{
scanf("%d",&c);
while(back_max>= && max_q[back_max].value<=c) back_max--;
max_q[++back_max].value=c;
max_q[back_max].index=j; while(back_min>= && min_q[back_min].value>=c) back_min--;
min_q[++back_min].value=c;
min_q[back_min].index=j; }
max_res[]=max_q[].value;//区间起始位置的最值
min_res[]=min_q[].value; for(int j=k;j<n;j++)//下标为k到n-1的元素
{
scanf("%d",&c);
if(max_q[front_max].index==j-k) front_max++;
if(min_q[front_min].index==j-k) front_min++; while(back_max>=front_max && max_q[back_max].value<=c) back_max--;
max_q[++back_max].value=c;
max_q[back_max].index=j; while(back_min>=front_min && min_q[back_min].value>=c) back_min--;
min_q[++back_min].value=c;
min_q[back_min].index=j; max_res[j-k+]=max_q[front_max].value;//每读入一个元素,更新一次区间,得到一个最值
min_res[j-k+]=min_q[front_min].value;
} for(int j=;j<n-k+;j++)
printf("%d ",min_res[j]);
printf("\n");
for(int j=;j<n-k+;j++)
printf("%d ",max_res[j]);
printf("\n");
return ;
}
OJ的结果是这样的(G++会超时,尚不明原因):

最开始没有考虑过期的问题,考虑之后担心队列不够长,需不需要写成循环的;但稍加分析会发现,front指针后移只发生在删除队首过期元素时,最多只发生n-k次,那么数组开到2n就可以了。
由于是不循环的队列,只需front和back两个指针就可完成所有需要的操作。(之前因为和一个计数变量混用,并是在边界判断时WA了很多次)
把前k个元素和之后的元素分开处理是为了考虑方便,AC了之后试图把它们合并起来然后并是又WA了。。。看来有时候不必过于追求代码的简炼,初学还是清晰更重要。
【POJ 2823 Sliding Window】 单调队列的更多相关文章
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- poj 2823 Sliding Window (单调队列入门)
/***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...
- POJ 2823 Sliding Window (单调队列)
单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...
- poj 2823 Sliding Windows (单调队列+输入输出挂)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 73426 Accepted: 20849 ...
- POJ 2823 Sliding Window 题解
POJ 2823 Sliding Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- POJ 2823 Sliding Window(单调队列入门题)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 190 ...
- POJ 2823 Sliding Window 【单调队列】
题目链接:http://poj.org/problem?id=2823 题目大意:给出一组数,一个固定大小的窗体在这个数组上滑动,要求出每次滑动该窗体内的最大值和最小值. 这就是典型的单调队列,单调队 ...
- 【单调队列】poj 2823 Sliding Window
http://poj.org/problem?id=2823 [题意] 给定一个长度为n的序列,求长度为k的滑窗内的最大值和最小值 [思路] 裸的单调队列 注意用C++提交,不然会T,orz我用G++ ...
- 题解报告:poj 2823 Sliding Window(单调队列)
Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is m ...
随机推荐
- Oracle 10g体系机构及安全管理《思维导图》
通过学习Oracle数据库后,我对数据库又有了进一步的了解,Oracle数据库 10g体系机构分为 物理和逻辑存储结构. 下面是我对Oracle数据库做的思维导图和笔记 (全屏查看:<思维导图& ...
- EditText获取焦点监听事件_EditText获取和失去焦点操作
今天在做搜索框的时候.遇到需要获取焦点之后做一些事情.实现方法也很简单.那就是绑定OnFocusChangeListener事件.实现 onFocusChange(View v, boolean ha ...
- css案例学习之用thead、tbody、tfoot实现漂亮的table布局
首先说说thead.tbody.tfoot <thead> <tbody> <tfoot> 无论前后顺序如何改变, <thead> 内的元素总是在表的最 ...
- Maximum Depth of Binary Tree 解答
Question Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along ...
- magento添加系统sections配置时应注意的事项
(1)只有在新增sections是需要增加对应的acl配置,这个配置可以放在config.xml中或者放在adminhtml.xml中 <adminhtml> <acl> &l ...
- Spring的MethodInvokingFactoryBean
通过MethodInvokingFactoryBean 可以向某静态方法注入参数. 如: <bean class="org.springframework.beans.factory. ...
- Spring的AOP2
本文是<AOP 那点事儿>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实用主义的方向在发展.沿着 Spri ...
- 本人对于JavaScript的一些总结
类型.值和变量 1.原始类型 数字.字符串和布尔 null空 undefined未定义 2.对象类型 3.类 Array Function Date RegExp Error 4.js ...
- android createbitmap函数内存溢出,求解怎样进行处理out of memory溢出问题
android createbitmap函数内存溢出,求解怎样进行处理out of memory溢出问题 android createbitmap函数内存溢出,求解怎样进行处理out of memor ...
- jQuery -> end方法的使用方法
我们在对结果集使用find.filter等方法时,会改变结果集. 这样的改变原先结果集的方法被称作destructive jQuery method jQuery cookbook有例如以下定义: A ...