题目链接:
题目意思:
给你n个组,以及每组的成员,让你建一个队列,开始队列为空。
有两种操作:
1、ENQUEUE x : 如果该队列中没有x的组友,就将x插入到队列的最后。如果有就插到该组的最后一个元素后面。
2、DEQUEUE : 出队操作,和普通队列一样执行操作。
解题思路:
问题的关键是怎样快速定位的插入的位置。分析知,如果该队列有组友,只会插到该组的最后一个位置即可,如果没有就插到队列的最后位置。
于是就可以想到用last[i]保存每组的最后一个元素的iterator,用team[i]表示i所属的队列。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<list>
#define eps 1e-6
#define INF (1<<20)
#define PI acos(-1.0)
using namespace std;
int team[1000000];
int main()
{
int n,ca(0);
int temp,cur;
char order[20];
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&temp);
for(int j=1;j<=temp;j++)
{
scanf("%d",&cur);
team[cur]=i; //元素所属的队列
}
}
list<int>mylist,templist; //templist 仅仅是作为一个常量标记结尾
list<int>::iterator last[1010];
for(int i=1;i<=n;i++)
last[i]=templist.end(); //开始每组在队列中的元素为零
printf("Scenario #%d\n",++ca);
while(scanf("%s",order)&&strcmp(order,"STOP"))
{
if(strcmp(order,"ENQUEUE")==0)
{
scanf("%d",&cur);
if(last[team[cur]]==templist.end()) //如果队列中还没有该组成员
last[team[cur]]=mylist.insert(mylist.end(),cur); //将该元素插到队列的最后
else
{
last[team[cur]]++; //如果队列中又该组的成员
last[team[cur]]=mylist.insert(last[team[cur]],cur); //插到该组的最后一个元素后面
}
}
else
{
cur=mylist.front();
printf("%d\n",cur);
list<int>::iterator tt;
tt=mylist.begin();
if(tt==last[team[cur]]) //注意判断一下出队的元素是不是最后一个元素,否则的话就要改变last的值
last[team[cur]]=templist.end();
mylist.pop_front();
}
}
putchar('\n');
}
}