【POJ 2259】Team Queue【队列】

题目大意:

题目链接:http://poj.org/problem?id=2259
t 个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么新人会插队到最后一个队友的身后。如果没有任何一个队友排队,则他会被排到长队的队尾。
要求支持如下3中指令:

  • E N Q U E U E x :编号为 x 的人进入长队。
  • D E Q U E U E :长队的队首出队。
  • S T O P :停止模拟

对于每个 D E Q U E U E 指令,输出出队的人的编号。


思路:

很明显的队列。但是插队操作却有点难实现。
为了完成插队操作,就要先建 n + 1 个队列。 q [ 0 ] 用来储存团队的排队情况(因为一个团队会在一起),而 q [ 1 ] q [ n ] 则储存每个团队的人员情况。
每当来了一个人时,就判断这个人的是否有队友在队伍中,如果有,就 q [ t e a m [ x ] ] . p u s h ( x ) 进入团队队列;如果没有,就先将这个团队进入总队列 q [ 0 ] . p u s h ( t e a m [ x ] ) ,再讲这个人进入团队队列 q [ t e a m [ x ] ] . p u s h ( x ) 。出队时,如果出队的人 x 还有队友在队伍中,那么就直接将 x 从团队队列中退出 q [ t e a m [ x ] ] . p o p ( ) ;如果没有队友了,那么不仅要然他从团队中退出,而且还要将整个团队从总队列退出 q [ 0 ] . p o p ( )


代码:

#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;

int n,m,team[1000001],x,sum;
string s;

int main()
{
    while (++sum)
    {
        scanf("%d",&n);
        if (!n) return 0;
        printf("Scenario #%d\n",sum);
        queue<int> q[1011];  //空间换时间
        memset(team,0,sizeof(team));
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&m);
            for (int j=1;j<=m;j++)
            {
                scanf("%d",&x);
                team[x]=i;
            }
        }
        while (1)
        {
            cin>>s;
            if (s[0]=='S') break;
            if (s[0]=='E')
            {
                scanf("%d",&x);
                if (!q[team[x]].size())  //没有队友
                 q[0].push(team[x]);
                q[team[x]].push(x);
            }
            if (s[0]=='D')
            {
                printf("%d\n",q[q[0].front()].front());  //输出
                q[q[0].front()].pop();
                if (!q[q[0].front()].size()) //没有队友了
                 q[0].pop();
            }
        }
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/SSL_ZYC/article/details/81701915