hdu~3530(单调队列)

来源:互联网 发布:八岐大蛇 蓝牙 mac 编辑:程序博客网 时间:2024/06/05 02:30

单调队列就是队列中的元素是单调递增或递减的。比如把 5 2 3 1 4 入队:

减:、、、、、、、、、、、增:

5 、、、、、、、、、、、、5

5 2 、、、、、、、、、、、2 

5 3 、、、、、、、、、、、2 3

5 3 1、、、、、、、、 、、1

5 4 、、、、、、、、、、、1 4


这个还是好理解的,但是,我们得会用单调队列这一特性去解决题目,抽象出题目中有类似的操作。

Subsequence

题意:

给三个数   n,x,y;

接下来n个数num[1~n];

求满足这个条件的最长区间长度:区间内最大值与最小值之差在 x~y之间。

方法:

单调队列记录下标。

由一个递增,一个递减的单调队列,可得前面的某个位置~当前位置的最大差值def=num[q1.front()]-num[q2.front()];

如果def>y,则让下标靠前的那个出队列。


上代码,看注释:

#include <stdio.h>#include <iostream>#include <deque>using namespace std;inline int  fmax(int a,int b){return a>b?a:b;}  int main(){    int n,x,y;    int num[100005];    while(scanf("%d %d %d",&n,&x,&y)!=EOF)    {        for(int i=1;i<=n;++i)            scanf("%d",&num[i]);        deque<int >q1,q2;   //两个队列,q1.front()存最大值,q2.front()存最小值        int max=0,last=0;   //last记录最后弹出元素的位置        for(int i=1;i<=n;i++){            while(!q1.empty() && num[i]>num[q1.back()]) q1.pop_back();//维护队列单调型            while(!q2.empty() && num[i]<num[q2.back()]) q2.pop_back();            q1.push_back(i);            q2.push_back(i);        //若对不空,且def>y,让下标靠前的出队。            while(!q1.empty() && !q2.empty() && num[q1.front()]-num[q2.front()]>y){                if(q1.front()>q2.front())                {                    last=q2.front();                    q2.pop_front();                }                else if(q1.front()<q2.front())                {                    last=q1.front();                    q1.pop_front();                }                else if(q1.front()>q2.front())                {                    last=q2.front();                    q1.pop_front();                    q2.pop_front();                }            }                    if(!q1.empty() && !q1.empty() && num[q1.front()]-num[q2.front()]>=x)                max=fmax(max,i-last);//若当前区间的def满足>=x,取区间最大长度        }        printf("%d\n",max);    }    return 0;}





0 0
原创粉丝点击