POJ 2823 Sliding Window/单调队列

来源:互联网 发布:mac nice to meet you 编辑:程序博客网 时间:2024/06/05 06:45

我的心愿是世界和平!

题目描述:第一行给数字n,k,接下来一行给出n个数字,在每k个数字中找到他的最大最小值。输出有两行,分别有n-k+1个数,第一行为最小值,第二行为最大值。注意:n的范围为1e6,暴力会超时。思路:维护一个单调递减的队列,例如 3 2 5 4,3为首,直接入队列(3),2比3小,入队列(3 2),5比2大,2出队列,5比3大,3出队列(5),4比5小,入队列(5 4),这样,队首即为当前数据的最大值,在此题中,需要记录队列中数据的位置,若已经超出k个,则队首出队列。单增队列同上。建议使用双端队列,若用数组模拟双端队列,需注意下标的控制。样例:8 3    1 3 -1 -3 5 3 6 7   // -1 -3 -3 -3 3 3   //3 3 5 5 6 7    3 2    3 2 1   //2 1   //3 2    8 3    -1 2 3 4 5 -9 6 2   //-1 2 3 -9 -9 -9   //3 4 5 5 6 6

双端队列

#include<iostream>#include<queue>#include<cstdio>#define sf scanfconst int M=1e6+10;using namespace std;struct node{    int x;    int y;} s[M+50];void Min_Max(int n,int k){    int i;    deque<node>q;    for(i=1; i<=k; i++)    {        if(q.empty()||s[i].x>=q.back().x)            q.push_back(s[i]);        else        {            while(s[i].x<q.back().x)            {                q.pop_back();                if(q.empty())                    break;            }            q.push_back(s[i]);        }    }    cout<<q.front().x;    for(i=k+1; i<=n; i++)    {        if(q.empty()||s[i].x>=q.back().x)            q.push_back(s[i]);        else        {            while(s[i].x<q.back().x)            {                q.pop_back();                if(q.empty())                    break;            }            q.push_back(s[i]);        }        while(q.back().y-q.front().y>=k)            q.pop_front();        cout<<" "<<q.front().x;    }    cout<<endl;}void Max_Min(int n,int k){    int i;    deque<node>q;    for(i=1; i<=k; i++)    {        if(q.empty()||s[i].x<=q.back().x)            q.push_back(s[i]);        else        {            while(s[i].x>q.back().x)            {                q.pop_back();                if(q.empty())                    break;            }            q.push_back(s[i]);        }    }    cout<<q.front().x;    for(i=k+1; i<=n; i++)    {        if(q.empty()||s[i].x<=q.back().x)            q.push_back(s[i]);        else        {            while(s[i].x>q.back().x)            {                q.pop_back();                if(q.empty())                    break;            }            q.push_back(s[i]);        }        while(q.back().y-q.front().y>=k)            q.pop_front();        cout<<" "<<q.front().x;    }}int main(){    int n,k,i,j;    sf("%d%d",&n,&k);    for(i=1; i<=n; i++)    {        sf("%d",&s[i].x);        s[i].y=i;    }    Min_Max(n,k);    Max_Min(n,k);}

数组模拟

#include<stdio.h>struct point{    int value;    int num;} max[1000001],min[1000001];int s[1000001],ss[1000001];int main(){    int t,i,j,m,n,k,p,maxp=0,minp=0,maxq=0,minq=0;    scanf("%d%d",&n,&k);    if(k==1)    {        for(i=0; i<n; i++)        {            scanf("%d",&m);            s[i]=m;            ss[i]=m;        }        t=n;    }    else    {        scanf("%d",&m);        max[0].value=min[0].value=m;        max[0].num=min[0].num=0;        p=0;        for(i=1; i<k-1; i++)        {            scanf("%d",&m);            if(m<=max[maxq].value)            {                max[++maxq].value=m;                max[maxq].num=i;            }            else            {                while(maxq>=maxp&&m>max[maxq].value)                    maxq--;                max[++maxq].value=m;                max[maxq].num=i;            }            if(m>=min[minq].value)            {                min[++minq].value=m;                min[minq].num=i;            }            else            {                while(minq>=maxp&&m<min[minq].value)                    minq--;                min[++minq].value=m;                min[minq].num=i;            }        }        t=0;        for(i=k-1; i<n; i++)        {            scanf("%d",&m);            while(max[maxp].num<p)                maxp++;            while(min[minp].num<p)                minp++;            if(m<=max[maxq].value)            {                max[++maxq].value=m;                max[maxq].num=i;            }            else            {                while(maxq>=maxp&&m>max[maxq].value)                    maxq--;                max[++maxq].value=m;                max[maxq].num=i;            }            if(m>=min[minq].value)            {                min[++minq].value=m;                min[minq].num=i;            }            else            {                while(minq>=minp&&m<min[minq].value)                    minq--;                min[++minq].value=m;                min[minq].num=i;            }            s[t]=min[minp].value;            ss[t]=max[maxp].value;            t++;            p++;        }    }    for(i=0; i<t; i++)        printf("%d ",s[i]);    printf("\n");    for(i=0; i<t; i++)        printf("%d ",ss[i]);}
原创粉丝点击