Problem 1894 志愿者选拔
Accept: 1178 Submit: 3719
Time Limit: 1500 mSec Memory Limit : 32768 KB
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
这个题目是对单调队列的考察,唉,我一开始用纯模拟的办法来做,赤裸裸的TLE,
唉,我不得不承认,我之前是一点都不懂单调队列的,但是当我仔仔细细的研究了
单调队列之后,却不得不觉得它很是神奇,它是一个数组,用head,和tail来表示其
队头和队尾的,对于那些比进入的元素大的数,通过tail--来进行压缩,然后直接覆
盖,这样就大大减小了空间的使用,让我实在觉得很是神奇,我决心多做几个单调队
列的题目,来加深一下对于单调队列的理解,单调队列的头与尾就是队里的最大值和
最小值,实在神奇的很.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 1000010
struct node
{
int num;//是第几位
int d;//人品值是多少
char s[10];//这个人叫啥
}unit[MAX];
int main()
{
int i,j,k;
int t;
scanf("%d",&t);
while(t--)
{
int head=0;//队头
int tail=-1;//队尾
int num=0;//入队之后这人的编号是多少的
int leave=0;//有多少个人离开了
char r[10];
scanf("%s",r);
while(scanf("%s",r))
{
if(r[0]=='E')
break;
else
if(r[0]=='C')
{
node temp;
scanf("%s%d",temp.s,&temp.d);
temp.num=++num;
while(head<=tail&&unit[tail].d<temp.d)
{
tail--;
}
/*
对于那些比放入元素要大的数,直接用tail--,
然后最后就可以进行覆盖
*/
tail++;
unit[tail]=temp;
}
else
if(r[0]=='Q')
{
while((unit[head].num<=leave)&&(head<=tail))
{
head++;
}
if(head>tail)
printf("-1\n");
else
{
printf("%d\n",unit[head].d);
}
}
else
leave++;
}
}
return 0;
}