UVA 540

有t个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么这个新人会插队到最后一个队友身后。如果没有任何一个队友排队,则他会排到长队的队尾。输入每个团队中所有队员的编号,要求支持如下3种指令(前两种指令可以穿插进行)。
ENQUEUE:编号为X的人进入长队。
DEQUEUE:长队队首出队。
STOP:停止模拟。
对于每个DEQUEUE指令,输出出队的人的编号。

输入

输入文件中有一组或多组测试数据。
每组测试数据开始有t个团队。下面t行,每行的第一个数字代表这个团队人数,后面是这几个人的编号。编号为0到999999之间的一个整数。
每组测试数据以“STOP”结束。
输入以t==0时结束。
警告:一个测试用例可能包含最多200000(二十万)个命令,所以实现
团队的队列应该是有效的。

输出

对于每组测试数据,先打印一句"Scenario #k",k是第几组数据。对于每一个"DEQUEUE"指令,输出一个出队的人的编号。每组测试数据后要换行,即使是最后一组测试数据。
样例输入
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
样例输出
Scenario #1
101
102
103
201
202
203

Scenario #2
259001
259002
259003
259004
259005
260001

题目大意:

有几个团队,然后每个团队有一些人,还有一个队列,在队列上定义了3种操作:

  • DEQUEUE 队首出队
  • ENQUEUE x 编号为 x 的人入队,如果队列中已经有x团队的人,那么x插到他所在团队的位置,如果没有则插到队尾。
  • STOP 停止模拟,退出循环

每个DEQUEUE询问输出出队的人的编号。

解题思路:

这道题表面上用了一个队列,实际上是用了多个队列,一个队列是总队列,存储已经入大队列的团队的编号,每个团队单独一个队列,用于存储当前团队入队情况。先用map映射一下这个人属于哪个团队,之后按照题目模拟即可。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int N = 1e3+50;
int k = 1;
int main()
{
    int n;
    while (cin >> n && n)
    {
        map<int ,int> mp;
        queue<int > q, q1[N];//q1存储每个团队
        for (int i = 1; i <= n; i ++)
        {
            int t;
            cin >> t;
            while (t--)
            {
                int s;
                cin >> s;
                mp[s] = i;//先映射个人与团队的关系
            }
        }
        printf("Scenario #%d
", k++);
        string op;
        while (cin >> op)
        {
            if (op == "STOP")
              break;
            if (op == "DEQUEUE")
            {
                int t = q.front();//看队首属于哪个团队
                cout << q1[t].front() << endl;
                q1[t].pop();
                if (q1[t].empty())//如果当前团队为空,则当前团队整体出队,再有人进来时插在团队的最后
                  q.pop();
            }
            else
            {
                int x;
                cin >> x;
                int t = mp[x];
                if (q1[t].empty())//如果这个团队为空,则说明该人是第一个入队的,该人所处的团队整体入队。
                  q.push(t);
                q1[t].push(x);
            }
        }
        cout << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Hayasaka/p/14294205.html