【题目大意】
有$n$个小组进行排队,每个小组中有若干人。当一个人来到队伍时,如果队伍中已经有自己小组的成员,他就直接插队排在自己小组成员的后面,否则就站在队伍的最后面。现在有若干个入队指令(编号为$X$的人进入队伍)和出队指令(队头的人出队),输出出队的顺序。
【思路分析】
因为在任意时刻,同一个小组的人在队伍中只会站在一起,所以我们建立一个队列$Q_0$存储队伍中所有小组的编号,再为每个小组$i$建立一个队列$Q_i$存储队伍中这个小组的所有成员。
当一个编号为$X$,组号为$Y$的人来到队伍时,我们直接把$X$插入$Q_Y$末尾,表明队伍最后出现了一个新的小组。
当接收到出队指令时,我们通过$Q_0$得知排在最前面的小组组号$Y$,然后再把$Q_Y$的队头出队。出队后如果$Q_Y$为空,就从$Q_0$开头删除$Y$,表明这个小组目前所有人已经离开。
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define g() getchar() 8 #define rg register 9 #define go(i,a,b) for(rg int i=a;i<=b;i++) 10 #define back(i,a,b) for(rg int i=a;i>=b;i--) 11 #define db double 12 #define ll long long 13 #define il inline 14 #define pf printf 15 using namespace std; 16 int fr(){ 17 int w=0,q=1; 18 char ch=g(); 19 while(ch<'0'||ch>'9'){ 20 if(ch=='-') q=-1; 21 ch=g(); 22 } 23 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 24 return w*q; 25 } 26 const int N=1002; 27 int n,m,c[1000002],t; 28 queue<int> q[N]; 29 char s[10]; 30 int main(){ 31 //freopen("","r",stdin); 32 //freopen("","w",stdout); 33 n=fr(); 34 while(n){ 35 go(i,1,n){ 36 m=fr(); 37 go(j,1,m){ 38 rg int x=fr(); 39 c[x]=i; 40 } 41 } 42 pf("Scenario #%d ",++t); 43 scanf("%s",s); 44 while(s[0]!='S'){ 45 if(s[0]=='E'){ 46 rg int x=fr(); 47 if(!q[c[x]].size()) q[0].push(c[x]); 48 q[c[x]].push(x); 49 } 50 else{ 51 rg int a=q[0].front(); 52 rg int x=q[a].front(); 53 pf("%d ",x); 54 q[a].pop(); 55 if(!q[a].size()) q[0].pop(); 56 } 57 scanf("%s",s); 58 } 59 n=fr();puts(""); 60 go(i,0,n) while(!q[i].empty()) q[i].pop(); 61 } 62 return 0; 63 }