主要的关键在于:不要试图让所有团队的人在一个队列里面,因为这样如果新入队的是一个前面团队的成员则必须先出队再入队。
应该把每个团队看做一个整体,用一个队列维护团队的顺序,用t个队列维护每个团队内部的顺序。
还有就是要维护成员编号到团队的映射关系,我这里用了一个一维数组,因为觉得1e6
也不是很大。看到书里面用的map
,觉得可以但是没必要。
我还用了一个数组去维护每个团队是否有人站队。看书里面的代码才发现完全是多余的,我们可以通过每个团队自己的队列是不是空来判断。
多组样例输入,应该把循环放在主函数里面,然后把初始化、读入、处理分开。多组样例的初始化十分重要,很容易出现问题。这里因为初始化不是很复杂我和读入放在了一起。
感觉自己的代码结构清晰一点。书里面的命名都好简洁,觉得自己如果这样命名很快就忘记是干什么的了。可能还是水平不够,驾驭不了太复杂的代码。
还有就是不要忘记关闭同步加速cin/cout
#include <iostream>
#include <string>
#include <array>
#include <queue>using namespace std;namespace {constexpr int MAX_TEAM = 1005;constexpr int MAX_MEM = 1e6 +5;array<int, MAX_MEM> id; //team id of each memberqueue<int> team; //team queuearray<queue<int>, MAX_TEAM> team_member;//member queue in each teamarray<bool, MAX_TEAM> is_in_queue;int t;int case_num = 0;
}void input() {while (!team.empty()) team.pop();int n, x;for (int i = 0; i < t; ++i) {is_in_queue[i] = false;while (!team_member[i].empty()) team_member[i].pop();cin >> n;while (n--) {cin >> x;id[x] = i;}}
}void deal() {string cmd;int x;int team_id;while (cin >> cmd && cmd[0] != 'S') {if (cmd[0] == 'E') {cin >> x;if (is_in_queue[id[x]]) {team_member[id[x]].push(x);} else {team.push(id[x]);is_in_queue[id[x]] = true;team_member[id[x]].push(x);}} else {team_id = team.front();auto &the_team = team_member[team_id];cout << the_team.front() << "\n";the_team.pop();if (the_team.empty()) {team.pop();is_in_queue[team_id] = false;}}}
}int main() {ios::sync_with_stdio(false);while (cin >> t) {if (t == 0) {break;}++case_num;cout << "Scenario #" << case_num << "\n";input();deal();cout << "\n";}return 0;
}