http://acm.fzu.edu.cn/problem.php?pid=1894
Problem Description
Input
输入 | 含义 | |
1 | C NAME RP_VALUE | 名字为NAME的人品值为RP_VALUE的同学加入面试队伍。(名字长度不大于5,0 <= RP_VALUE <= 1,000,000,000) |
2 | G | 排在面试队伍最前面的同学面试结束离开考场。 |
3 | Q | 主面试官John想知道当前正在接受面试的队伍中人品最高的值是多少。 |
Output
Sample Input
2STARTC Tiny 1000000000C Lina 0QGQENDSTARTQC ccQ 200C cxw 100QGQC wzc 500QEND
Sample Output
10000000000-1200100500
Hint
数据较大建议使用scanf,printf 不推荐使用STL单调队列:单调队列即保持对列中的元素单调递增(或递减)的这样一个序列,可以从两头删除,但是只能从队尾插入。单调队列的具体作用在于,由于保持队列中的元素满足单调性,对于上述问题中的每个j,可以用O(1)的时间找到对应的s[i].保持队列元素单调递增的话,队首元素便是所要的元素了。
实现和维护方法:建立一个队列,删除在开头和结尾,加入元素只能在队尾。详见代码:
560200 | 2014-06-01 11:25:25 | Accepted | 1894 | GNU C++ | 1140 ms | 8056KB | 985B |
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn=1000002;
struct node
{
int key,tag;
node(int k=0,int t=0):key(k),tag(t){}//赋值技巧
}q[maxn];
int head,tail;
int main()
{
int t,i,j,val;
char s[120];
scanf("%d",&t);
q[0]=-1;
while(t--&&scanf("%s",s))
{
head=1;tail=0;i=0;j=1;
while(~scanf("%s",s))
{
if(!strcmp(s,"END"))
break;
if(s[0]=='C')
{
scanf("%s %d",s,&val);
while(head<=tail&&q[tail].key<=val)//为保证队列中的元素单调递增,在队尾加入新元素之前要把队尾的比该元素元素大的元素全部删去
tail--;
q[++tail]=node(val,++i);//加入新元素
}
else if(s[0]=='G')
{
while(head<=tail&&q[head].tag<=j)//在开头把已经面试完的人剔除。
head++;
j++;
}
else
printf("%d\n",head>tail?-1:q[head].key);//head>tail说明队列已经为空队列
}
}
return 0;
}