POJ 2259 Team Queue(STL队列)

转自:https://www.cnblogs.com/yjlblog/p/7056746.html

题目背景

队列和优先级队列是大多数计算机科学家都知道的数据结构。但是团队队列却不被人熟知,尽管在生活中经常出现。比如,午餐时间的食堂门口的队列就是一个团队队列。在一个团队队列中,每个元素属于一个团队。如果一个元素进入一个队列,它首先从头到尾地搜寻这个队列——检查是否它的队友(在同一个团队称之为队友)也在这个队列里。如果有,它就排在它队友的后面(:-D就是插队咯~~)。如果没有,它就排在整个队列的最后,成为新的最后一名(/(ㄒoㄒ)/~真是不幸)。在普通队列中出队是这样的:元素从头到尾的被处理,按他们出现在团队队列里的顺序。你的任务是写一个程序模拟这样一个团队队列。

输入

输入文件会包含一个或多个测试样例。每一个测试样例由代表团队数量的t(1<=t<=1000)开始。然后t只团队描述如下,每一个团队由一个表示元素个数的数字,以及每个元素组成。元素属于整型,并且范围在0到999999(一百万减一)之间。一个团队可能有多达1000个元素。最后,指令列表如下。有三种不同的指令:ENQUEUE x——x进入团队队列。DEQUEUE x——处理第一个元素并将其移除STOP——结束一个测试样例。当t是0时,输入终止。警告:一个测试样例可能多达200000(/(ㄒoㄒ)/~~二十万)条指令,所以团队队列的实现应该是有效率的:入队和出队都应该花费常数时间。

输出

对应每个测试样例,首先输出一行“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

分析

题目明确告诉了我们使用队列。使用一个队列排列团队;再使用一个队列排列元素。题目中说了出队入队只能花费常数时间,所以要在元素和团队之间建立映射关系而不能简单地使用数组存下元素。

代码

#include<cstdio>  
#include<queue>  
#include<map>  
using namespace std;  
const int maxt = 1000 + 10;  
int main()  
{  
    int t, kase = 0;  
    while(scanf("%d", &t) == 1 && t) {  
        printf("Scenario #%d\n", ++kase);  
  
        map<int , int> team;//映射作用是编号x对应它的队伍i  
        for(int i = 0; i < t; i++) {  
            int n,x;  
            scanf("%d", &n);  
            while(n--) { scanf("%d", &x); team[x] = i;}  
        }  
  
        queue<int> q, q2[maxt];  
        //两个队列是本题的核心  
        //q存放的是队伍,q2存放的是按增序排列的所有的队伍以及队伍下的编号  
        //即q存放团队整体队列,例{3,1,2}  
        //q2存放团队队列,例{103,101,102},{201},{301,303}  
        for(;;) {  
        int x;  
        char cmd[10];  
        scanf("%s", cmd);  
        if(cmd[0] == 'S') break;//遇到STOP停止  
        else if(cmd[0] == 'D'){  
            int t = q.front();//用变量t表示团队整体队列的队首  
            printf("%d\n",q2[t].front()); q2[t].pop();//输出这个队首队伍的第一个人,然后把该人出队  
            if(q2[t].empty()) q.pop();//如果该队伍在整个队列中只有一个人,则q的队首出队,即该队伍出队  
        }else if(cmd[0] == 'E'){  
            scanf("%d", &x);  
            int t = team[x];//通过map找出x的队列序号  
            if(q2[t].empty()) q.push(t);//如果该队还没有人排在队中,则该队列插入队尾  
            q2[t].push(x);//把该队伍的人插入到q2的该队中  
            }  
        }  
        printf("\n");  
    }  
    return 0;  
}

 

posted @ 2018-07-22 21:22  Somnus、M  阅读(194)  评论(0编辑  收藏  举报