POJ 2259 Team Queue(队列)

题目原网址:http://poj.org/problem?id=2259

题目中文翻译:

Description

队列和优先级队列是大多数计算机科学家已知的数据结构。 然而,Team Queue并不是很知名,尽管它常常发生在日常生活中。 例如,在午餐时间,门萨前面的队列就是Team Queue。

 

在Team Queue中,每个元素都属于一个团队。 如果一个元素进入队列,它首先从头到尾搜索队列,以检查它的一些队友(同一队的元素)是否已经在队列中。 如果是,它会进入Team Queue后面。 如果不是,它会从尾部进入队列并成为新的最后一个元素(运气不好)。 出队是在常规队列中完成的:元素按照出现在队列中的顺序从头到尾进行处理。

 

你的任务是编写一个模拟这样的Team Queue的程序。

Input

输入将包含一个或多个测试用例。 每个测试用例都以团队的数量t开始(1 <= t <= 1000)。 然后是团队描述,每个描述包含属于团队的元素数量和元素本身。 元素是0到999999之间的整数。一个团队最多可以包含1000个元素。

最后,下面是一系列命令。 有三种不同的命令:

ENQUEUE x - 在队列中输入元素x

DEQUEUE - 处理第一个元素并将其从队列中移除

STOP - 测试用例结束

输入将以t的值0结束。

注意:一个测试用例最多可以包含200000个(20万个)命令,所以团队队列的实现应该是高效的:一个元素的入队和出队只需要一定的时间。

Output

对于每个测试用例,首先打印一行表示“Scenario #k”的行,其中k是测试用例的编号。 然后,对于每个DEQUEUE命令,将出队元素打印单独一行上。 在每个测试用例之后打印一行空白行,即使是在最后一行之后。

Sample Input

2

3 101 102 103

3 201 202 203

ENQUEUE 101

ENQUEUE 201

ENQUEUE 102

ENQUEUE 202

ENQUEUE 103

ENQUEUE 203

DEQUEUE

DEQUEUE

DEQUEUE

DEQUEUE

DEQUEUE

DEQUEUE

STOP

2

5 259001 259002 259003 259004 259005

6 260001 260002 260003 260004 260005 260006

ENQUEUE 259001

ENQUEUE 260001

ENQUEUE 259002

ENQUEUE 259003

ENQUEUE 259004

ENQUEUE 259005

DEQUEUE

DEQUEUE

ENQUEUE 260002

ENQUEUE 260003

DEQUEUE

DEQUEUE

DEQUEUE

DEQUEUE

STOP

0

Sample Output

Scenario #1

101

102

103

201

202

203

 

Scenario #2

259001

259002

259003

259004

259005

260001

解题思路:

看题目,如果我们按照题目,用一个队列来维护整个Team Queue,用STL则无法实现,而手写也不是非常容易实现.所以,我们要想一个更简单的办法:

既然题目说这里面有许多不同的团队,那么我们为什么不用一个大的队列只记录团队号的顺序,再用一些小的队列来记录每个团队内元素的先后顺序.

每当读入元素,我们判断它所在的团队是否在大序列中,如果在,则直接将这个元素插入到它的团队队列中;如果不在,则将它的团队号插入到大队列中,再将它插入到它的团队队列中.

每当要输出元素,便找大队列中最前面的团队的第一个元素,弹出,如果这个团队的序列空了,则将这个团队的团队号从大队列中弹出去.

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<string>
 6 
 7 using namespace std;
 8 
 9 int n;
10 queue<int > uo;
11 int op = 1;
12 int kk[1000000];//记录每个元素是哪个团队的 
13 
14 struct kkk{//表示每个团队 
15     queue<int > qq;//小队列 
16     bool vis;//表示这个团队是否在大队列中 
17 }e[1001];
18 
19 void work(int oo) {//解题过程 
20     cout << "Scenario #" << oo << endl;
21     string l;
22     while(cin >> l && l != "STOP") {
23         if(l == "ENQUEUE") {
24             int p;
25             cin >> p;
26             e[kk[p]].qq.push(p);
27             if(e[kk[p]].vis == 0) {
28                 uo.push(kk[p]);
29                 e[kk[p]].vis = 1;
30             }
31         }
32         if(l == "DEQUEUE") {
33             cout << e[uo.front()].qq.front() << endl;
34             e[uo.front()].qq.pop();
35             if(e[uo.front()].qq.empty()) {
36                 e[uo.front()].vis = 0;
37                 uo.pop();
38             }
39         }
40         if(l == "STOP") break;
41     }
42 }
43 
44 void chus() {//初始化 
45     memset(kk,0,sizeof(kk));
46     while(!uo.empty()) uo.pop();
47     for(int i = 1;i <= n; i++) {
48         while(!e[i].qq.empty())
49             e[i].qq.pop();
50         e[i].vis = 0;
51     }
52 }
53 
54 int main() {
55     while(cin >> n && n != 0) {
56         chus();
57         for(int i = 1;i <= n; i++) {
58             int k,l;
59             scanf("%d",&k);
60             for(int j = 1;j <= k; j++) {
61                 scanf("%d",&l);
62                 kk[l] = i;
63             }
64         }
65         work(op);
66         cout << endl;
67         op++;
68     }
69     return 0;
70 }

 

转载于:https://www.cnblogs.com/lipeiyi520/p/10720525.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值