poj 2823 单调队列 deque写法

Sliding Window

Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 46435   Accepted: 13417
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

Source

POJ Monthly--2006.04.28, Ikki

#include <iostream>
#include <cstdio>
#include <queue>
#include <deque>

using namespace std;
typedef pair<int, int> P;
#define maxn 1000000 + 10

deque<P> Q1;
deque<P> Q2;
int n, k;
int Min[maxn], Max[maxn];

int main()
{
    while(~scanf("%d%d", &n, &k))
    {
        while(!Q1.empty()) Q1.pop_back();
        while(!Q2.empty()) Q2.pop_back();
        int x;
        for(int i=1; i<=n; i++)
        {
            scanf("%d", &x);
            while(!Q1.empty() && Q1.back().first >= x) Q1.pop_back();
            Q1.push_back(P(x, i));
            if(i >= k)
                {
                    while(!Q1.empty() && Q1.front().second <= i-k) Q1.pop_front();
                    Min[i] = Q1.front().first;
                }

            while(!Q2.empty() && Q2.back().first <= x) Q2.pop_back();
            Q2.push_back(P(x, i));
            if(i >= k)
                {
                    while(!Q2.empty() && Q2.front().second <= i-k) Q2.pop_front();
                    Max[i] = Q2.front().first;
                }
        }

        for(int i=k; i<=n; i++)
            i == n ? printf("%d\n", Min[i]) : printf("%d ", Min[i]);

        for(int i=k; i<=n; i++)
            i == n ? printf("%d\n", Max[i]) : printf("%d ", Max[i]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 11:15:49

poj 2823 单调队列 deque写法的相关文章

Sliding Window POJ - 2823 单调队列模板题

Sliding Window POJ - 2823 单调队列模板题 题意 给出一个数列 并且给出一个数m 问每个连续的m中的最小\最大值是多少,并输出 思路 使用单调队列来写,拿最小值来举例 要求区间最小值 就是维护一个单调递增的序列 对于样例 8 3 1 3 -1 -3 5 3 6 7 我们先模拟一遍 1.队列为空 1 进队 队列:1 2.3>队尾元素 3 进队 队列: 1 3 3.-1小于队尾元素,一直从尾部出队知道找到比-1小的元素或者队列为空 队列:-1 当队列中元素大于m的时候从队头删

poj 2823 单调队列

//单调队列求滑动窗口的最大值和最小值 //题意是给一个n个数,在每k个数区间内 //求最大值和最小值 //单调队列:队列中的元素是单调的. //求最小值的时候:进队的时候将队尾部大于当前要进的元素全部出队 //这样,队列的头部就是最小值 //反之,求最大值也是一样 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std

poj 2823 单调队列裸题

两个队列分别维持最大和最小 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; struct node { int mi,ma; }num[1000010]; int sax[1000010],sin[1000010]; int ida[1000010],idi[1000010]; int main() { int n,m,i,j,k,a; while(~scanf(&

POJ 3017 单调队列dp

Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 Description Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subseque

POJ 2838 单调队列

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 55309   Accepted: 15911 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

poj 3017 单调队列

只能说是代码美如画.(当然我是指内在逻辑不是我的代码风格,队长看到要理解哈,啊哈哈哈哈哈哈哈哈) 正常思路咯,f[i]=f[j]+max(a[j+1],a[j+2]....a[i]),枚举j,显然硬来会超时,所以需要有一个单调队列来时时把最大值尽快弄出来并且需要一些剪枝: 剪枝条件有两个,一个是和不能超过m,一个是显然f[i]是个非严格递增序列,根据这两个条件剪枝: 则建立单调队列,每当插入新的i时将前面先把和小于等于m的条件做好,然后对于j<i,如果a[j]<a[i]就可以把j丢弃,那么显然

单调队列 数组写法qwq

1 #include<bits/stdc++.h> 2 #define ll unsigned long long 3 #define LL long long 4 const int MOD=1e9+7; 5 const int maxn=2e5+5; 6 using namespace std; 7 8 int que[maxn],a[maxn]; 9 void que_min(int n) 10 { 11 int l=0,r=0;//头尾相等 12 for(int i=1;i<=n

poj2823Sliding Window——单调队列

题目:http://poj.org/problem?id=2823 单调队列模板. 代码如下: #include<iostream> #include<cstdio> using namespace std; int n,k,a[1000005],mx[1000005],mn[1000005]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d&

[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