算法思想——单调队列(Foj志愿者问题)

来源:互联网 发布:vue.js实战 pdf 编辑:程序博客网 时间:2024/04/27 16:19

单调队列顾名思义就是一个单调的队列。下面分析一下用它来干什么,以及怎么样维护。
先来个问题说明一下吧。

有一些学生来找我面试(宝宝是HR哦),我让他们进屋排队,现在我不定时的询问在屋里的最高分。让面试完的出屋,同时也根据我的心情让面试者进屋。
我的描述不是很好,不明白的自行看题吧
题目

其实这就是在根据条件维护一个特殊的序列,是这个序列保持某种性质。(现在是维护单调的性质)。
目的在于简化查询,特点是不定时的更新序列,不定的查询。
下面介绍一下实现思想:以单增队列为例:维护一个序列,元素如果比最后一个元素小,把这个元素放到最后,如果不比最后一个元素小的话,就从前向后遍历,直到找到一个值比现在的元素小,就用现在的元素代替这个值,并且将其后面的全舍掉。(先到于实际队列中的那些人公用这个最大值)
下面上代码;

#include<cstdio>#include<iostream>#include<cstring>int a[1000010];int b[1000010];using namespace std;int main(){    int T,v,shu,t1,t2,t,w;    char temp[100],s[100];    scanf("%d",&T);    while(T--)    {    t = 0;     t1 = 0;\\现实队列的队头    w = 0;\\尾序号     t2 = 0;\\所维护队列的对头    shu = 0//用来记录当前的人数;        memset(a, -1 ,sizeof(a));        memset(b,-1,sizeof(b));        while(1){        scanf("%s",temp);        if(strcmp(temp,"END") == 0)        {            break;        }        if(strcmp(temp,"C") == 0)        {            scanf("%s%d",s,&v);            a[t++] = v;            shu++;            if(b[w] >= v)            {                b[++w] = v;            }            else            {                for(int i = t2; b[i] != -1||w == 0;++i)                {                    if(v > b[i])                    {                        b[i] = v;                        w = i;                        b[i + 1]  = -1 ;                        break;                    }                }            }        }        if(strcmp(temp,"G") == 0)        {            if(shu != 0)            {                if(a[t1] == b[t2])                {                    t2++;                }                t1++;                shu--;            }        }        if(strcmp(temp,"Q") == 0)        {            if(shu != 0)            {                printf("%d\n",b[t2]);            }            else            {                printf("-1\n");            }        }    }    }    return 0;}

总结:单调队列其实就是实现多个数,对某个特殊值的公用。