ACdreamer
梦之河上,一叶扁舟!
版权声明:本文为博主原创文章,未经博主允许不得转载。
单调队列是这样一个队列,队列中的所有元素是单调递增或者单调递减。它可以在队首或队尾删除元素,但是只能在队尾插入元素。由于每个元素入队和出队一次,所以维护队列的均摊时间复杂度为O(1)。
题目:http://poj.org/problem?id=2823
题意:给一个数组a[],求它连续m个元素中的最小值和最大值。比如输入:
8 3
1 3 -1 -3 5 3 6 7
那么输出:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
分析:我们用一个数组q[]来记录这个单调队列所有元素的下标,h为队首,t为队尾。那么现在就来模拟样例:
首先h初始化为1,t初始化为0。
(1)插入第一个元素 q[] = {1},h = 1,t = 1 队列中的元素个数小于3,不输出。
(2)插入第二个元素 q[] = {1,2},h = 1,t = 2 队列中的元素个数小于3,不输出。
(3)插入第三个元素 q[] = {3},h = 1,t = 1 因为3号元素比1和2号元素都小,所以一直挤到最
前面,1号和2号元素出队,此时队列中的元素个数等于3,输出队首元素值。
(4)插入第四个元素 q[] = {4},h = 1,t = 1 同样的道理,3号元素出队,输出队首元素值。
(5)插入第五个元素 q[] = {4,5},h = 1,t = 2 输出队首元素。
(6)插入第六个元素 q[] = {4,6},h = 1,t = 2 输出队首元素。
(7)插入第七个元素 q[] = {6,7},h = 2,t = 3 输出队首元素。
(8)插入第八个元素 q[] = {6,7,8},h = 2,t = 4 输出队首元素。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 1000005;
int n,m;
int a[N],q[N];
void MinQ()
{
int t = 0 ,h = 1;
q[1] = 1;
for(int i=1; i<=n; i++)
{
if(i - q[h] == m) h++;
if(t == h-1 || a[i] > a[q[t]])
{
t++;
q[t] = i;
}
else
{
while(t >= h && a[i] <= a[q[t]])
{
q[t] = i;
t--;
}
t++;
}
if(i >= m) printf("%d ",a[q[h]]);
}
puts("");
}
void MaxQ()
{
int t = 0 ,h = 1;
q[1] = 1;
for(int i=1; i<=n; i++)
{
if(i - q[h] == m) h++;
if(t == h-1 || a[i] < a[q[t]])
{
t++;
q[t] = i;
}
else
{
while(t >= h && a[i] >= a[q[t]])
{
q[t] = i;
t--;
}
t++;
}
if(i >= m) printf("%d ",a[q[h]]);
}
puts("");
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
MinQ();
MaxQ();
return 0;
}
题目:http://acm.fzu.edu.cn/problem.php?pid=1894
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 1000005;
struct Node
{
int id;
int val;
Node(int id = 0,int val = 0)
{
this->id = id;
this->val = val;
}
};
Node q[N];
char str[105];
int main()
{
int T;
scanf("%d",&T);
q[0] = -1;
while(T--)
{
scanf("%s",str);
int i = 0,j = 1;
int head = 1,tail = 0;
while(scanf("%s",str))
{
if(!strcmp(str,"END")) break;
if(str[0] == 'C')
{
int val;
scanf("%s %d",str,&val);
while(head <= tail && q[tail].val <= val) tail--;
q[++tail] = Node(++i,val);
}
else if(str[0] == 'G')
{
while(head <= tail && q[head].id <= j) head++;
j++;
}
else
printf("%d\n",head > tail ? -1:q[head].val);
}
}
return 0;
}
-
顶
- 2
-
踩
- 1
- 上一篇像素与颜色
- 下一篇Python数据库的连接
- 个人资料
-
- 访问:2193004次
- 积分:23590
- 等级:
- 排名:第299名
- 原创:478篇
- 转载:42篇
- 译文:0篇
- 评论:488条
- 文章搜索
- 文章分类
- 文章存档
- 2015年10月(1)
- 2015年06月(4)
- 2015年05月(3)
- 2015年04月(4)
- 2015年03月(38)
- 2015年02月(4)
- 2015年01月(1)
- 2014年12月(2)
- 2014年11月(5)
- 2014年10月(1)
- 2014年09月(4)
- 2014年08月(2)
- 2014年06月(1)
- 2014年05月(7)
- 2014年04月(10)
- 2014年03月(8)
- 2014年02月(8)
- 2014年01月(12)
- 2013年12月(16)
- 2013年11月(31)
- 2013年10月(20)
- 2013年09月(28)
- 2013年08月(49)
- 2013年07月(27)
- 2013年06月(16)
- 2013年05月(42)
- 2013年04月(18)
- 2013年03月(29)
- 2013年02月(26)
- 2013年01月(15)
- 2012年12月(3)
- 2012年11月(8)
- 2012年10月(9)
- 2012年09月(8)
- 2012年08月(11)
- 2012年07月(3)
- 2012年06月(46)
- 阅读排行
- 评论排行
- 推荐文章
- 最新评论
- HDU4372(第一类斯特林数)
milesgu:@Flynn_curry:代码确实有问题,需要特判x+y>n+1的时候输出0
- 逆元详解
lfb637:能不能转载一下,方便学习
- 深度理解链式前向星
Binary_Heap:意外发现一个好博客
- K-D树
yxlshk:C++那一版的建树时,没有按照方差大小选举用来比较的维度?目测是根据深度依次选取维度。
- 中国剩余定理
weixin_38686780:poj2891 可以用欧几里得扩展直接求吧
- 0x5f3759df的数学原理
lindexi_gd:厉害
- 决策树之ID3算法
mingtian715:学习了
- ISODATA算法
vector_yuge:@wzr22:运行可以按ctrl+f5,而不是只按f5
- 二次同余方程的解
a27038:@u010510549:x一定是整数,所以(a+sqrt(w))^((p-1)/2)也一定是整数,只...
- 数学公式及定理
asd1170586462:大神你好 第一个公式 把n=1,k=2,带入怎么算的是0