- 小组队列
有 n 个小组要排成一个队列,每个小组中有若干人。
当一个人来到队列时,如果队列中已经有了自己小组的成员,他就直接插队排在自己小组成员的后面,否则就站在队伍的最后面。
请你编写一个程序,模拟这种小组队列。
输入格式:
输入将包含一个或多个测试用例。
对于每个测试用例,第一行输入小组数量 t。
接下来 t 行,每行输入一个小组描述,第一个数表示这个小组的人数,接下来的数表示这个小组的人的编号。
编号是 0 到 999999 范围内的整数。
一个小组最多可包含 1000 个人。
最后,命令列表如下。 有三种不同的命令:
1、ENQUEUE x - 将编号是 x 的人插入队列;
2、DEQUEUE - 让整个队列的第一个人出队;
3、STOP - 测试用例结束
每个命令占一行。
当输入用例 t=0 时,代表停止输入。
需注意:测试用例最多可包含 200000(20 万)个命令,因此小组队列的实现应该是高效的:
入队和出队都需要使用常数时间。
输出样例
对于每个测试用例,首先输出一行 Scenario #k,其中 k 是测试用例的编号。
然后,对于每个 DEQUEUE 命令,输出出队的人的编号,每个编号占一行。
在每个测试用例(包括最后一个测试用例)输出完成后,输出一个空行。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
queue<int>q[1011];
queue<int>s_q;
map<int, int>vis;
map<int, int>s_vis;
int main() {
int t, d, m, cnt = 0;
string s;
while (cin >> t && t) {
cnt++;
while (!s_q.empty())s_q.pop();
vis.clear(), s_vis.clear();
for (int i = 1; i <= t; i++)
while (!q[i].empty())q[i].pop();
for (int i = 1; i <= t; i++) {
cin >> m;
//cout<<m<<endl;
for (int j = 1; j <= m; j++) {
cin >> d;
//cout<<d<<endl;
vis[d] = i;
}
}
printf("Scenario #%d\n", cnt);
//cout << "999" << endl;
int x;
while (cin >> s, s != "STOP") {
//cout << s << " " << "lll" << endl;
if (s == "ENQUEUE") {
cin >> x;
//cout << s << ' ' << d << endl;
if (q[vis[x]].empty()) {//(错)!s_vis[vis[x]](人走了就不会回来?)
s_q.push(vis[x]);
s_vis[vis[x]] = 1;
}
q[vis[x]].push(x);
} else if (s == "DEQUEUE") {
//while (q[s_q.front()].empty())s_q.pop();
int e = s_q.front();
cout << q[e].front() << endl;
q[e].pop();
if (q[e].empty())s_q.pop();
}
}
puts("");
}
return 0;
}
思维惯性了以为人从队伍里离开了就不会回去了,但是数据里显然不是。