题目:Team Queue
Queues and Priority Queues are data structures which are known to most computer scientists. The Team Queue, however, is not so well known, though it occurs often in everyday life. At lunch time the queue in front of the Mensa is a team queue, for example.
In a team queue each element belongs to a team. If an element enters the queue, it first searches the queue from head to tail to check if some of its teammates (elements of the same team) are already in the queue. If yes, it enters the queue right behind them. If not, it enters the queue at the tail and becomes the new last element (bad luck). Dequeuing is done like in normal queues: elements are processed from head to tail in the order they appear in the team queue.
Your task is to write a program that simulates such a team queue.
Input
The input will contain one or more test cases. Each test case begins with the number of teams t (1<=t<=1000). Then t team descriptions follow, each one consisting of the number of elements belonging to the team and the elements themselves. Elements are integers in the range 0 - 999999. A team may consist of up to 1000 elements.
Finally, a list of commands follows. There are three different kinds of commands:
ENQUEUE x - enter element x into the team queue
DEQUEUE - process the first element and remove it from the queue
STOP - end of test case
The input will be terminated by a value of 0 for t.
Output
For each test case, first print a line saying "Scenario #k", where k is the number of the test case. Then, for each DEQUEUE command, print the element which is dequeued on a single line. Print a blank line after each test case, even after the last one.
样例:
Sample Input
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
Sample Output
Scenario #1
101
102
103
201
202
203
Scenario #2
259001
259002
259003
259004
259005
260001
题目大意:就是先输入t行,表示t个小队,其中的数值就是这个小队的队员。然后之后再专门组成一个大队列,这个大队列和小队之间没有关系的,但是在依次排队的时候,如果这个正准备排队的成员在之前有队友在前面,则排到队友的那一群的后面,如果没有队友则要排到大队列的队尾。
思路:找一个数组还记录这个小队是否在大队里,且在大队列用一个二维数组存,其中每一行的首元素表示为这一行是哪个小队的,之后根据这个正要进入大队列的成员确定其所在小队是否已经在大队列中,如果在则放到这个小队的那一行的最后,如果不在则在大队列中的最后表示这个新的小队的存在,然后再这一个小队的这一行的第一个元素为这个成员。然后在出队伍的时候,依次从大队列的第一个小队的第一个成员出,因为这题非常容易超时,所以把千万避免遍历,所以要把大队列的队首记下来,大队列的队尾记录下来,每个小队的第一个元素记下来,每个小队的个数记下来。还是因为时间问题,这题千万不能移动元素,因为这样非常耗时,所以要改变的是记录大队列队首和大队列队尾的数值,还有改变小队的队首与每个小队的个数;(也是因为这个原因,没办法用链表进行,只能用数组进行);
新技巧:对于这种查找耗时很长的队列问题,用链表就相对麻烦很多了,所以这时候就考虑用数组就可以,而且这题还出现了范围,所以用数组可以。(这题如果要改成链表就要把每个小队作为一个队列然后进行队尾插入,队首删除),不过因为这样会非常的麻烦,因为要为每个存在于大队列的小队建立一个链表。所以不如用数组方便些(数组会出现内存的问题,这个也要注意)。(所以对于数据结构的问题的处理,用链表和数组理论上都可以,但有简单和方便,还有时间问题的区别,具体选择哪个具体分析)(但记住,数组查找方便,插入到中间不方便,删除也不方便(这题不是直接删除),队列问题的数组插入还是比较简单。链表查找麻烦,因为有很大的可能性需要遍历,但是插入的时候简单,只需要改变节点的指向即可,删除也简单,尤其是对于队列的链表处理,只用改变头节点指向和尾节点指向即可。);
自己的建议:对于数据结构的问题,最好一上来先考虑用链表来进行,毕竟动态分配要灵活的多。当用链表实在麻烦,不方便,或者说超时的问题的时候,再去考虑用数组。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int number[1005];
int s_mumber[1000005];
int s_num[5005][1005];
int main()
{
int t,j,i,num=0,n,ttt,start;
char ss[10];
while(scanf("%d",&t)!=EOF&&t!=0)
{
for(i=0;i<t;i++)
{
scanf("%d",&n);
for(j=0;j<n;j++)
{
scanf("%d",&ttt);
number[j]=0;
s_mumber[ttt]=i;
}
}
int times=0;
num++;start=0;
printf("Scenario #%d\n",num);
while(1)
{
scanf("%s",ss);
if(ss[0]=='E')
{
scanf("%d",&ttt);
i=s_mumber[ttt];
if(number[i]==0)
{
s_num[times][0]=i;
s_num[times][1]=1;
s_num[times][2]=3;
s_num[times][3]=ttt;
number[i]=1;
times++;
}
else
{
for(j=start;j<times;j++)
if(i==s_num[j][0])
break;
s_num[j][1]++;
s_num[j][s_num[j][2]+s_num[j][1]-1]=ttt;
}
}
else if(ss[0]=='S')
break;
else if(ss[0]=='D')
{
if(s_num[start][1]==0)
{
number[s_num[start][0]]=0;
start++;
printf("%d\n",s_num[start][s_num[start][2]]);
s_num[start][2]++;
s_num[start][1]--;
}
else
{
printf("%d\n",s_num[start][s_num[start][2]]);
s_num[start][2]++;s_num[start][1]--;
}
}
}
printf("\n");
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。