题目链接:点击这里
因为在任何时刻,同一个小组的人只要来到了队伍,就会站在一起,所以我们建立一个队列 存储队伍中所有小组的编号,再为每个小组 建立一个队列 存储队伍中这个小组的所有成员,一共 个队列。换言之,用 个队列维护组内顺序, 个队列维护组间顺序。
当一个编号为 ,组号为 的人来到队伍时,我们直接把 插入 末尾。如果在插入之前 是空的,则还要把 插入到 末尾,表明队伍最后出现了一个新的小组。
当接收到出队指令时,我们通过 得知排在最前面的小组组号 ,然后再把 的队头出队。出队后如果 为空,就从 开头删除 ,表明这个小组目前所有人已经离开。
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 1010;
int main()
{
int t;
int cnt = 0;
while(~scanf("%d",&t)&&t)
{
printf("Scenario #%d\n", ++cnt);
queue<int> q[maxn]; //维护组内顺序
queue<int> group; //维护组间顺序
unordered_map<int,int> mmp;
for(int i = 1; i <= t; ++i)
{
int n;
scanf("%d", &n);
for(int j = 1; j <= n; ++j)
{
int id;
scanf("%d", &id);
mmp[id] = i;
}
}
string op;
while(cin>>op&&op!="STOP")
{
if(op=="ENQUEUE")
{
int id;
scanf("%d", &id);
int g = mmp[id];
if(q[g].empty()) group.push(g);
q[g].push(id);
}
else if(op=="DEQUEUE")
{
if(!group.empty())
{
int g = group.front();
if(!q[g].empty())
{
printf("%d\n", q[g].front());
q[g].pop();
if(q[g].empty()) group.pop();
}
}
}
}
printf("\n");
}
return 0;
}