题目大意:
队列和优先级队列是大多数计算机工作者所知道的数据结构。然而,Team Queue就没那么多人知道了,尽管它经常出现在日常生活中。例如,在午餐时间,Mensa前面的队列是一个Team Queue。
在Team Queue中,每个元素都属于一个Team。如果一个元素进入队列,它首先从头到尾搜索队列,以检查其队友(同一团队的元素)是否已经在队列中。如果是,它就会进入它们后面的队列。如果没有,它进入尾部的队列并成为新的最后一个元素。像在正常队列中一样进行队列化:元素按照它们在队列中出现的顺序从头到尾进行处理。
您的任务是编写一个模拟此类Team Queue的程序。
输入
输入将包含一个或多个测试用例。每个测试用例以团队数量t(1 <= t <= 1000)开始。然后是团队描述,每个团队描述由属于团队的元素数量和元素本身组成。元素是0到999999范围内的整数。一个团队最多可包含1000个元素。
最后,下面是一个命令列表。有三种不同的命令:
ENQUEUE x - 将元素x输入团队队列
DEQUEUE - 处理第一个元素并将其从队列中删除
STOP- 测试用例结束
对于t,输入将以0的值终止。
警告:测试用例最多可包含200000个命令,因此团队队列的实现应该是高效的:元素的入队和出队应该只占用一个时间。
输出
对于每个测试用例,首先打印一行“Scenario #k”,其中k是测试用例的编号。然后,对于每个DEQUEUE命令,打印在一行上出列的元素。在每个测试用例后打印一个空行,即使在最后一个测试用例之后。
样例输入
2
3 101 102 103
3 201 202 203
ENQUEUE 101
ENQUEUE 201
ENQUEUE 102
ENQUEUE 202
ENQUEUE 103
ENQUEUE 203
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
2
5 259001 259002 259003 259004 259005
6 260001 260002 260003 260004 260005 260006
ENQUEUE 259001
ENQUEUE 260001
ENQUEUE 259002
ENQUEUE 259003
ENQUEUE 259004
ENQUEUE 259005
DEQUEUE
DEQUEUE
ENQUEUE 260002
ENQUEUE 260003
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
0
样例输出
Scenario #1
101
102
103
201
202
203
Scenario #2
259001
259002
259003
259004
259005
260001
分析;
第一步
本题牵涉团队,我们可以开一个队列其元素为团队队列,而团队队列的元素则是每个人。
第二步
由于ENQUEUE后为一个元素,而复杂度又不能超过O(n)
因此我们需快速找到输入元素属于哪个团队,这里我们可以用一个数组(有点不好想到),输入时用下标记录数值,而数值为团队。
第三步
模拟即可。
代码如下
#include
#include
#include
using namespace std;
deque sq[1005];
char s[10];
int n,m,k,x,t=0,b[1000005];
int main()
{
while(scanf("%d",&n) && n)
{
t++;
for(int i=1;i<=1000;i++)
{
sq[i].clear();//清空队列;
}
printf("Scenario #%d\n",t);
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
scanf("%d",&k);
b[k]=i;//建立团队;
}
}
while(scanf("%s",s) && s[0]!='S')
{
if(s[0]=='E')
{
scanf("%d",&x);
if(!sq[b[x]].size())
sq[0].push_back(b[x]);//sq[0]用于存团队,团队中还未有元素入队则将团队插入队尾。
sq[b[x]].push_back(x);//将人插入团队队尾。
}
else
{
int f=sq[0].front();//取团队队列里的第一个团队;
printf("%d\n",sq[f].front());
sq[f].pop_front();//输出第一个团队队列的第一个元素并出队。
if(!sq[f].size())//如果这是该团队最后一个元素。
sq[0].pop_front();//将团队出队。
}
}
}
return 0;
}