【SOJ 392】志愿者选拔

【题目】

题目描述:

西博会马上就要开幕了,电子科技大学组织了一次志愿者选拔活动。
参加志愿者选拔的同学们排队接受面试官们的面试。参加面试的同学们按照先来先面试并且先结束的原则接受面试官们的考查。
面试中每个人的英语口语能力是主要考查对象之一。
作为主面试官的 John 想知道当前正在接受面试的同学队伍中口语能力值最高的是多少。于是他请你帮忙编写一个程序来计算。

输入格式:

输入数据第一行为一整数 T,表示有 T(T≤5) 组输入数据。
每组数据第一行为 “START”,表示面试开始。
接下来的数据中有三种情况:
1 C NAME KY_VALUE 名字为 NAME 的口语能力值为 KY_VALUE 的同学加入面试队伍。

(名字长度不大于 5 5 5 0 0 0KY_VALUE 1 , 000 , 000 , 000 1,000,000,000 1,000,000,000)。

2 G 排在面试队伍最前面的同学面试结束离开考场。
3 Q 主面试官 John 想知道当前正在接受面试的队伍中口语能力最高的值是多少。
最后一行为 “END”,表示所有的面试结束,面试的同学们可以依次离开了。
所有参加面试的同学总人数不超过 1,000,000

输出格式:

对于每个询问 Q,输出当前正在接受面试的队伍中口语能力最高的值,如果当前没有人正在接受面试则输出 -1

样例数据:

输入
2
START
C Tiny 1000000000
C Lina 0
Q
G
Q
END
START
Q
C ccQ 200
C cxw 100
Q
G
Q
C wzc 500
Q
END

输出
1000000000
0
-1
200
100
500


【分析】

还是一道比较简单的题吧

这道题的话,NAME 其实是没有用的,我们只用维护 KY_VALUE 就能解决此题

具体就是维护一个单调递减的队列,那么队首元素就是最优解

要注意的是对于 G 操作,不能直接弹队首,因为我们可能用队首把前面不优的元素弹掉了,而此次操作需要弹掉的元素就是之前已经出队了的元素,这样直接弹就会出问题,其实只用记录一下此时谁应该出队,然后判断一下是否是队首就行了

还有就是建议再加点优化,比如用 g e t c h a r getchar getchar 读入,用 p u t c h a r putchar putchar 输出之类的(不然好像过不了

【代码】

#include
#include
#include
#include
#define N 1000005
using namespace std;
int val[N];
char s[10],name[10];
deque<int>q;
int main()
{
	int t,x;
	scanf("%d",&t);
	while(t--)
	{
		q.clear();
		int num=0,pos=0;
		while(~scanf("%s",s+1))
		{
			if(s[1]=='S')  continue;
			else  if(s[1]=='E')  break;
			else  if(s[1]=='G')  {pos++;if(q.front()==pos)q.pop_front();}
			else  if(s[1]=='Q')  printf("%d\n",q.empty()?-1:val[q.front()]);
			else
			{
				scanf("%s",name);
				scanf("%d",&x);val[++num]=x;
				while(!q.empty()&&x>=val[q.back()])  q.pop_back();
				q.push_back(num);
			}
		}
	}
	return 0;
}

你可能感兴趣的:(#,队列)