队列和优先级队列是大多数计算机科学家都知道的数据结构。但是团队队列却不被人熟知,尽管在生活中经常出现。比如,午餐时间的食堂门口的队列就是一个团队队列。
在一个团队队列中,每个元素属于一个团队。如果一个元素进入一个队列,它首先从头到尾地搜寻这个队列——检查是否它的队友(在同一个团队称之为队友)也在这个队列里。如果有,它就排在它队友的后面(:-D就是插队咯~~)。如果没有,它就排在整个队列的最后,成为新的最后一名(/(ㄒoㄒ)/~真是不幸)。在普通队列中出队是这样的:元素从头到尾的被处理,按他们出现在团队队列里的顺序。
你的任务是写一个程序模拟这样一个团队队列。
输入文件会包含一个或多个测试样例。每一个测试样例由代表团队数量的t(1<=t<=1000)开始。然后t只团队描述如下,每一个团队由一个表示元素个数的数字,以及每个元素组成。元素属于整型,并且范围在0到999999(一百万减一)之间。一个团队可能有多达1000个元素。
最后,指令列表如下。有三种不同的指令:
ENQUEUE x——x进入团队队列。
DEQUEUE x——处理第一个元素并将其移除
STOP——结束一个测试样例。
当t是0时,输入终止。
警告:一个测试样例可能多达200000(/(ㄒoㄒ)/~~二十万)条指令,所以团队队列的实现应该是有效率的:入队和出队都应该花费常数时间。
对应每个测试样例,首先输出一行“Scenario #k”,其中k表示第几次测试。然后,每一个“DEQUEUE”指令打印包含出队的元素(单独占一行)。打印一空行在每一个测试样例之后,即使是最后一个测试样例。
题目明确告诉了我们使用队列。使用一个队列排列团队;再使用一个队列排列元素。题目中说了出队入队只能花费常数时间,所以要在元素和团队之间建立映射关系而不能简单地使用数组存下元素。
#include
#include
#include
#include
#include
#include
using namespace std;
//#define yydebug
#define MaxSize 1024
int main(int argc, char **argv)
{
#ifdef yydebug
ifstream cin("in.txt");
ofstream cout("out.txt");
#endif
int t;
int loopCount = 0;
while (cin >> t)
{
// t == 0 时退出测试
if (0 == t)
break;
// 读入t个团队
map<int, int> mapElements;
for (int i = 0; i < t; i++)
{
int eleCount;
cin >> eleCount;
// 读入一个团队的元素
for (int j = 0; j < eleCount; j++)
{
int tmp;
cin >> tmp;
// 标记所属团队
mapElements[tmp] = i;
}
}
cout << "Scenario #" << ++loopCount << endl;
// 执行指令
queue<int> q, queElements[MaxSize];
string cmdStr;
while (cin >> cmdStr)
{
if ("STOP" == cmdStr)
break;
if ("ENQUEUE" == cmdStr)
{
int element;
cin >> element;
int team = mapElements[element];
if (queElements[team].empty())
{
q.push(team);
}
queElements[team].push(element);
}
if ("DEQUEUE" == cmdStr)
{
int team = q.front();
if (queElements[team].size() > 0)
{
cout << queElements[team].front() << endl;
queElements[team].pop();
}
if (queElements[team].empty())
{
q.pop();
}
}
}
cout << endl;
}
return 0;
}
代码的逻辑并不复杂,但是因为对STL不熟悉,queue的成员函数怎么用都不知道。还以为pop()会返回元素,google之后就发现自己错得离谱。看来,真是工欲善其事必先利其器。