ACM-单调队列之Sliding Window——poj2823

Sliding Window

Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 36326   Accepted: 10762
Case Time Limit: 5000MS

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window
moves rightwards by one position. Following is an example:

The array is [1 3 -1 -3 5 3 6 7], and k is 3.

Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position.

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

题目:http://poj.org/problem?id=2823

之前在讨论 hdu魔板 这道题的时候,有人提到了O(1)队列,于是 度娘搜索到了这道题。做一下咯~

①什么是O(1)队列?
O(1)队列又称单调队列,顾名思义,就是队列中的元素是单调的。
要么单调递增,要么单调递减。
那么,构建单调队列有什么用呢?
我们维护一个队列后,我们查找当前队列内元素最大值/最小值  就可以是O(1)的速度了。
或许有人(比如我刚开始就想过)问:用优先队列,设置一下优先级不就可以了。
但是,要知道STL的东东,都挺耗时间的,尤其是 优先队列。
一般用单调队列做的题,对时间要求比较高,所以优先队列显然不能满足要求。
②单调队列如何维护
以单调递增队列来举例:

1、如果队列的长度一定,先判断队首元素是否在规定范围内,如果超范围则增长队首。

2、每次加入元素时和队尾比较,如果当前元素小于队尾且队列非空,则减小尾指针,队尾元素依次出队,直到满足队列的调性为止

要特别注意头指针和尾指针的应用。

参考资料:http://www.cnblogs.com/neverforget/archive/2011/10/13/ll.html

http://xuyemin520.is-programmer.com/posts/25964

And 这道题就可以解决了。
/**************************************
***************************************
*        Author:Tree                  *
*From :http://blog.csdn.net/lttree    *
* Title : Sliding Window              *
*Source: poj 2823                     *
* Hint  : 单调队列                   *
***************************************
**************************************/
#include <stdio.h>
#define MAX 1000001
int n,k;
int pre1,pre2,lst1,lst2,len_max,len_min;    // 两个队列的头指针与尾指针,最大值的下标,最小值的下表
int num[MAX],Increase[MAX],Decrease[MAX],Max[MAX],Min[MAX];      // Num存数据,递增与递减队列,最大值,最小值的数组。
// 递增序列的压入操作
void in_max(int i)
{
    while( pre1<=lst1 && num[ Increase[lst1] ]<num[i] )
        --lst1;
    Increase[++lst1]=i;

    // 如果大于等于k个数,就需要向最大值数组赋值
    if( i>=k )
    {
        if(Increase[pre1]<=i-k)
            pre1++;
        Max[len_max++]=num[ Increase[pre1] ];
    }
}
// 递减序列的压入操作
void in_min(int i)
{
    while( pre2<=lst2 && num[ Decrease[lst2] ]>num[i] )
        --lst2;
    Decrease[++lst2]=i;

    // 如果大于等于k个数,就需要向最小值数组赋值
    if( i>=k )
    {
        if(Decrease[pre2]<=i-k)
            pre2++;
        Min[len_min++]=num[ Decrease[pre2] ];
    }
}
int main()
{
    int i;
    while( ~scanf("%d%d",&n,&k) )
    {
        // 初始化
        pre1=pre2=len_max=len_min=0;
        lst1=lst2=-1;

        // 读入数据
        for(i=1;i<=n;++i)
        {
            scanf("%d",&num[i]);
            in_max(i);
            in_min(i);
        }

        // 输出数据
        for( i=0;i<len_min-1;++i )
            printf("%d ",Min[i]);
        printf("%d\n",Min[len_min-1]);
        for( i=0;i<len_max-1;++i )
            printf("%d ",Max[i]);
        printf("%d\n",Max[len_max-1]);
    }
    return 0;
}


ACM-单调队列之Sliding Window——poj2823,布布扣,bubuko.com

时间: 2025-01-15 17:29:16

ACM-单调队列之Sliding Window——poj2823的相关文章

【单调队列】POJ2823-Sliding Window

单调队列经典题之一. [思路] 设置两个单调队列分别记录最大值和最小值.对于每一个新读入的数字,进行两次操作(对于求最大值和最小值中的某一个而言),一是若队首不在滑窗范围内则删去:二是删去队末比当前值小(或大)的值,并将当前值插入对尾.每一次的最小(大)值就是当前单调队列的队首. [错误点] 一定要写while (scanf("%d%d",&n,&k)!=EOF),否则会WA. 我一开始的做法是这样的:先把第一个数插入队尾,再从第二个数开始进行后续操作.这样的问题在于如

[ACM] poj 2823 Sliding Window(单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 36212   Accepted: 10723 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

POJ2823 Sliding Window (单调队列)

POJ2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38342   Accepted: 11359 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the ve

[ACM] poj 2823 Sliding Window (单调队列)

高一时,学校组织去韶山游玩,我没去,这次趁着五一,总算去了我心心念念的韶山.其实我知道所有的景点都是差不多的,可是因为电视剧<恰同学少年>,让我对毛泽东有了进一层的了解,所以,我一直都想去看看. 有两个同学一男一女是我理想的旅友,可是女生不想去,而男士回家了.所以,我独自一人去了. 准备工作:一小包饼干,一小包山楂片,两个苹果,一瓶水,帽子(防晒),墨镜(装酷) 早晨5:30起床了,洗漱完毕,吃完早餐,赶到公交车站牌那里,才6点过几分.公交车6:31才到,等了近半个小时(公交车上明明说是6:0

POJ2823 Sliding Window(单调队列)

单调队列,我用deque维护.这道题不难写,我第二次写单调队列,1次AC. ----------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<deque> #define rep(i,r) for(int i=0;i<r;i++) #define clr(x,c) memset

POJ2823 Sliding Window (单调队列的基本应用)

题目链接: http://poj.org/problem?id=2823 题意: 给定一个长度为n的序列,求每个长度为k的区间的最大值与最小值 分析: 单调队列的基本应用 代码如下: <span style="font-size:14px;">#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector

poj 2823 Sliding Window (单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 46705   Accepted: 13485 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

POJ2823 Sliding Window【双端队列】

求连续的k个中最大最小值,k是滑动的,每次滑动一个 用双端队列维护可能的答案值 如果要求最小值,则维护一个单调递增的序列 对一开始的前k个,新加入的如果比队尾的小,则弹出队尾的,直到新加入的比队尾大,加入队尾 从第k+1个到最后一个,按照上述规则,压入新数,然后弹出队首元素(满足队首元素对应原来序列的位置必须在视窗内,否则,继续弹出下一个) #include <cstdio> #include <cstdlib> #include <iostream> #include

poj 2823 Sliding Window (单调队列入门)

1 /***************************************************************** 2 题目: Sliding Window(poj 2823) 3 链接: http://poj.org/problem?id=2823 4 题意: 给一个数列,找所有连续k个数的最小值和最大值. 5 算法: 单调队列(入门) 6 ******************************************************************