POJ 2823 Sliding Window

来源:互联网 发布:淘宝一千零一夜活动 编辑:程序博客网 时间:2024/06/08 18:48

题意:给出一列数字,给出一个区间,区间会向右移动,问区间从一头移动到另一头,这个过程中区间内的最大值和最小值。
解法:单调队列

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;#define maxn 1000010struct node{    int num , id;//值和序号    node(){}    node(int _num , int _id)    {        num = _num;        id = _id;    }}q1[maxn],q2[maxn];//递增单调队列,递减单挑队列。int a[maxn],maxans[maxn],minans[maxn];int main(){    int n , k , head1 , rear1 , head2 , rear2 , maxi , mini ;    head1 = rear1 = head2 = rear2 = maxi = mini = 0;    scanf("%d%d",&n,&k);    for(int i = 1 ; i <= n ; i++)    scanf("%d",&a[i]);    for(int i = 1 ; i <= n ; i++)    {//递增单调队列        while(head1 < rear1 &&q1[rear1-1].num >= a[i]) rear1--;        q1[rear1++] = node(a[i],i);        while(head1 < rear1 &&q1[head1].id <= i-k) head1++;        if(i >= k&&mini<=n-k) minans[mini++] = q1[head1].num;    }    for(int i = 1 ; i <= n ; i++)    {//递减单调队列        while(head2 < rear2 &&q2[rear2-1].num <= a[i]) rear2--;        q2[rear2++] = node(a[i],i);        while(head2 < rear2 &&q2[head2].id <= i-k) head2++;        if(i >= k&&maxi<=n-k) maxans[maxi++] = q2[head2].num;    }    for(int i = 0 ; i < mini-1 ; i++)        printf("%d ",minans[i]);    printf("%d\n",minans[mini-1]);    for(int i = 0 ; i < maxi-1 ; i++)        printf("%d ",maxans[i]);    printf("%d\n",maxans[maxi-1]);    return 0;}
0 0
原创粉丝点击