UVA540 Team Queue(双queue)

题目大意

有一条长队,每个人均唯一属于一个组(有编号),执行给定操作序列,输出相应结果。操作如下:

(假设长队q1)

  • ENQUEUE x:标号为x的人入队,若q1中存在和x属于同一组的人,则将x插入长队中同组的最后一个人之后;否则插入长队最后一个之后

  • DEQUEUE:长队第一个人出队

  • STOP:结束该测试用例

思路分析

题意清晰后,问题变得简单,有多种解决思路,比较朴素的使用链表处理,但这里为了练习队列(队列也是链表实现的),采用双队列实现(相当于二级索引/二维数组(队列1–第一维,队列2–第二维)):

  • 队列2:存储位于长队中的同一组的人
  • 队列1:存储位于长队中的组号

数据结构如下:

queue<int> q1, q2[1010]; // 总团队队列,组内部队列

可定义map<int, int> team;存储人x的编号到组别编号,便于查询

注意点
每个测试用例后均需一空行,包括最后一个
命令判断时注意提取共性,简化代码
命令判断时,由于每个命令首字母均不同,因此可直接比较首字母,提高效率
由于map仅用于查询,也可用由哈希算法实现的unordered_map实现
若是超时,将cin/cout全改为scanf/printf

#include<bits/stdc++.h>
using namespace std;
int t, n, x, maxn;
string cmd;
int main() {
	int Kcase = 1;
	freopen("in.txt", "r", stdin);
	while (cin >> t && t) {
		map<int, int>team;//编号x -> 组别编号
		for (int i = 0; i < t; ++i) {
			cin >> n;
			for (int j = 0; j < n; ++j) {
				cin >> x;
				team[x] = i;
			}
		}
		printf("Scenario #%d\n", Kcase++);
		queue<int>q1, q2[1010];//双队列存储 总团队队列,组内部队列
		while (cin >> cmd && cmd[0] != 'S') {
			if (cmd[0] == 'E') { // 入队
				cin >> x;
				if (q2[team[x]].empty()) { // 组内不存在队员
					q1.push(team[x]); // 进入总队列
				}
				q2[team[x]].push(x); // 组内不存在队员,加入总队列最后
			}
			else if (cmd[0] == 'D') { // 出队
				printf("%d\n", q2[q1.front()].front());
				q2[q1.front()].pop();
				if (q2[q1.front()].empty()) q1.pop(); // 维护总队列
			}
		}
		puts("");
	}
	return 0;
}
posted @ 2020-05-29 10:47  Koshkaaa  阅读(175)  评论(0编辑  收藏  举报