这道题目、主要是对队列的灵活应用。其实就是一道模拟题目,只要你洞察出题目的本质就十分简单。题目意思大体是有多组测试数据,每组的一开始是一个数字t,代表一共有多少的团队,接着是t行输入,每一行都由一个数字n开头,表示队伍的人数。在这之后,输入诺干行的操作指令,E x代表入编号为x的入队列,这里的队列是一个新的而且只有一个的新队列。D代表就是出队列、同时输出该元素、S表示停止模拟。
题目的具体要求是,每次入队里前,先从队列头扫描到队列尾,如果队列里有队友,就排在队友们的最后面(不是该队友的后面,是整队队友的最后面)。如果没有队友则,直接排在队列的最后面。出队列的没什么特别的了。
Keys:其实我们可以通过简单的模拟、发现。由第一个队员到最后一个队员入队列,或者中间有其他出队列。该队列始终可以看成是两个队列的队列。又因为题目要求常数的时间、
所以我们不可能把时间浪费在某个队员属于哪一个队里,所以可以用映射、也就是map来解决这个问题。map<int, int>这个结构刚好能映射这种关系。接下去就是要有一个q2[maxn]来表示所有初始化的队列。一个q来表示新队列,这个q其实就是队列的队列。
1 #include <queue>
2 #include <string>
3 #include <map>
4 #include <iostream>
5 using namespace std;
6
7 const int maxn = 1024;
8
9
10 int main() {
11
12 int t, n, k = 0;
13 while (cin >> t, t) {
14 // 列队编号
15 cout << "Scenario #" << ++k << endl;
16 int qid = 1;
17 map<int, int> team;
18 while (t--) {
19 cin >> n;
20 for (int i = 0; i < n; i++) {
21 int uid;
22 cin >> uid;
23 team[uid] = qid;
24
25 }
26 qid++;
27 }
28
29 // uid是队员编号、 tid是那一对队的编号
30 queue<int> q,q2[maxn];
31 string op;
32 int uid;
33
34 while (cin >> op, op[0] != 'S') {
35
36 // 入队列
37 if ('E' == op[0]) {
38 cin >> uid;
39 int tid = team[uid];
40 if (q2[tid].empty()) q.push(tid);
41 q2[tid].push(uid);
42
43 }
44 // 出队列
45 if ('D' == op[0]) {
46
47 int tid = q.front();
48 int x = q2[tid].front();
49 q2[tid].pop();
50 cout << x << endl;
51 if (q2[tid].empty()) q.pop();
52
53 }
54
55 }
56
57 cout << endl;
58
59
60 }
61
62 }