UVA.540 Team Queue (队列)

UVA.540 Team Queue (队列)

题意分析

有t个团队正在排队,每次来一个新人的时候,他可以插入到他最后一个队友的身后,如果没有他的队友,那么他只能插入到队伍的最后。题目中包含以下操作:
1.ENQUEUE x :表示编号为x的入队;
2.DEQUEUE:长队的队首出队。
3.STOP:停止模拟
并且对于每一个DEQUEUE操作,输出队首的编号。

如果我们直接用一个队列来模拟的话,是无法实现的,原因在于,我们无法向队列中间插入元素。那么题目中还有一条重要的性质,那么就是:可以插入到他最后一个队友的身后。 有了这条性质,就可以保证每个队伍的顺序不会改变。比如说:
现在队列为空,101进队,201进队,301进队。然后102在进队,那么102一定是在101的后面;202进队,202一定会在201的后面,也就是说,队伍10X、20X、30X的相对顺序是不会改变的。

PS:这与哪个队伍首先入队的顺序有关。
PPS:上述例子认为10X为一队,20X为一队,30X位一队。

于是我们就可以分为2种队列:一种是表示队伍的队列,一种是表示队伍之间各个成员的队列。出队时,先根据队伍队列,决定是哪个队伍的成员线出队,当某队伍成员全部出队后,将这个队伍的队列销毁(即出队),看下一个是哪个队伍,再对下一个队伍的每个成员依次出队。直到停止模拟。

代码总览

#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#define nmax 1005
using namespace std;

int main()
{
    //freopen("in.txt","r",stdin);
    int n,cas = 1;
    while(scanf("%d",&n) && n){
        printf("Scenario #%d\n",cas++);
        map<int,int> mmp;
        for(int j = 0; j<n; ++j){
            int m,t;
            scanf("%d",&m);
            for(int i = 0 ; i<m; ++i){ scanf("%d",&t);mmp[t] = j;}        
        }
        char com[10];
        queue<int> t,team[nmax];
        while(1){
            scanf(" %s",com);
            if(com[0] == 'S')break;
            if(com[0] == 'D'){
                int temp = t.front();
                printf("%d\n",team[temp].front());
                team[temp].pop();
                if(team[temp].empty()) t.pop();
            }else if(com[0] == 'E'){
                int id;
                scanf("%d",&id);
                if(team[mmp[id]].empty())t.push(mmp[id]);
                team[mmp[id]].push(id);
            }
        }
        printf("\n");
    }
    return 0;
}
posted @ 2017-03-01 20:39  pengwill  阅读(92)  评论(0编辑  收藏  举报