您的位置:首页 > 其它

单调队列--poj2823 Sliding Window

2017-10-08 20:50 363 查看
n个元素的数组,大小为k的窗口。

求窗口右滑时,窗口中的最大最小值。

#include <iostream>

#include <cstdio>

#include <deque>

#include <vector>

using namespace
std;

struct pr{

    int num,pos;

};

int n,k;

deque<pr> dq1,dq2;//需要出队入队,所以

const int maxn =
1e6 + 5;

int v1[maxn],v2[maxn];

void seg_max(int t,int i)

{

    while (!dq1.empty() &&
dq1.front().pos <= i -
k) {//先判断队首元素是否失效,是的话,先出队

        dq1.pop_front();

    }

    if(dq1.empty())
dq1.push_back(pr{t,i});//从队尾入队新的元素

    else{

        while(!dq1.empty() &&
dq1.back().num < t){//单调递减队列,区间最大值
//该处可以二分找

            dq1.pop_back();

        }

        dq1.push_back(pr{t,i});

    }

    v1[i] =
dq1.front().num;

}

void seg_min(int t,int i)

{

    while (!dq2.empty() &&
dq2.front().pos <= i -
k) {

        dq2.pop_front();

    }

    if(dq2.empty())
dq2.push_back(pr{t,i});

    else{

        while (!dq2.empty() &&
dq2.back().num > t) {

            dq2.pop_back();

        }

        dq2.push_back(pr{t,i});

    }

    v2[i] =
dq2.front().num;

}

int read()

{

    int x=0,f=1;char
ch=getchar();

    while(ch<'0' | ch>'9') {if(ch=='-')
f=-1;ch=getchar();}

    while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

void Out(int aa)

{

    if(aa <
0){putchar('-');aa = -aa;}

    if(aa>9)

        Out(aa/10);

    putchar(aa%10+'0');

}

int main()

{

    n =
read();k=
read();

    int t;

    for (int i =
0; i < n; i ++) {

        t = read();

        seg_max(t, i);

        seg_min(t,i);

    }

    for (int i =
k - 1; i <
n; i ++) {

        Out(v2[i]);

        if(i ==
n - 1)
putchar('\n');

        else
putchar(' ');

    }

    for (int i =
k - 1; i <
n; i ++) {

        Out(v1[i]);

        if(i ==
n - 1)
putchar('\n');

        else
putchar(' ');

    }

    return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: