Team Queue

韓小妹發表於2018-08-12

題意

有t個團隊的人正在排一個長隊。每次新來一個人時,如果他有隊友在排隊,那麼這個新人會插隊到最後一個隊友身後。如果沒有任何一個隊友排隊,則他會排到長隊的隊尾。輸入每個團隊中所有隊員的編號,要求支援如下3種指令(前兩種指令可以穿插進行)。
ENQUEUE:編號為X的人進入長隊。
DEQUEUE:長隊隊首出隊。
STOP:停止模擬。
對於每個DEQUEUE指令,輸出出隊的人的編號。

輸入

輸入檔案中有一組或多組測試資料。
每組測試資料開始有t個團隊。下面t行,每行的第一個數字代表這個團隊人數,後面是這幾個人的編號。編號為0到999999之間的一個整數。
每組測試資料以“STOP”結束。
輸入以t==0時結束。
警告:一個測試用例可能包含最多200000(二十萬)個命令,所以實現
團隊的佇列應該是有效的。

輸出

對於每組測試資料,先列印一句"Scenario #k",k是第幾組資料。對於每一個"DEQUEUE"指令,輸出一個出隊的人的編號。每組測試資料後要換行,即使是最後一組測試資料。

樣例輸入

2
3 101 102 103
3 201 202 203
ENQUEUE 101
ENQUEUE 201
ENQUEUE 102
ENQUEUE 202
ENQUEUE 103
ENQUEUE 203
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
2
5 259001 259002 259003 259004 259005
6 260001 260002 260003 260004 260005 260006
ENQUEUE 259001
ENQUEUE 260001
ENQUEUE 259002
ENQUEUE 259003
ENQUEUE 259004
ENQUEUE 259005
DEQUEUE
DEQUEUE
ENQUEUE 260002
ENQUEUE 260003
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
0

樣例輸出

Scenario #1
101
102
103
201
202
203

Scenario #2
259001
259002
259003
259004
259005
260001

AC碼:

#include<cstdio>  
#include<queue>  
#include<map>  
using namespace std;  
const int maxt = 1000 + 10;  
int main()  
{  
    int t, kase = 0;  
    while(scanf("%d", &t) == 1 && t)
	{  
        printf("Scenario #%d\n", ++kase);
        map<int,int> team;//對映作用是編號x對應它的隊伍i  
        for(int i = 0; i < t; i++)
		{//共有t個隊伍 
            int n,x;  
            scanf("%d", &n);//第i+1個隊伍有n名隊員 
            while(n--) 
			{
				scanf("%d", &x);//輸入n名成員的編號 
				team[x] = i;//編號x對應它的隊伍i
			}  
        }  
  
        queue<int> q, q2[maxt];//q是團隊的佇列(長隊),而q2[i]是團隊i成員的佇列  
        //兩個佇列是本題的核心  
        //q存放的是隊伍,q2存放的是按升序排列的所有的隊伍以及隊伍下的編號  
        //即q存放團隊整體佇列,例{3,1,2}  
        //q2存放團隊佇列,例{103,101,102},{201},{301,303}  
        for(;;) 
		{
        	int x;  
        	char cmd[10];  
        	scanf("%s", cmd);//輸入操作指令 
        	if(cmd[0] == 'S') break;//遇到STOP停止  
        	else 
        	{
				if(cmd[0] == 'D')
				{//DEQUEUE:長隊隊首出隊
            		int t = q.front();//用變數t表示團隊整體佇列的隊首  
            		printf("%d\n",q2[t].front());
					q2[t].pop();//輸出這個隊首隊伍的第一個人,然後把該人出隊  
            	    if(q2[t].empty())
					q.pop();//如果該隊伍在整個佇列中只有一個人,則q的隊首出隊,即該隊伍出隊  
        		}
				else
				{ 
					if(cmd[0] == 'E')
					{//ENQUEUE:編號為X的人進入長隊
            			scanf("%d", &x);  
            			int t = team[x];//通過map找出x的佇列序號  
            			if(q2[t].empty()) q.push(t);//如果該隊還沒有人排在隊中,則該佇列插入隊尾  
            			q2[t].push(x);//把該隊伍的人插入到q2的該隊中  
            		} 
				}
        	}  
    	}
        printf("\n");  
    }  
    return 0;  
}

有關“優先佇列”的知識,參考部落格:優先佇列的排序寫法https://blog.csdn.net/hanyue0102/article/details/81609790

 

相關文章