题解 Team Queue(UVa540)紫书P118queue的应用

先上Vjudeg地址:点击这里

题目:

有t个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么这个新人会插队到最后一个队友身后。如果没有任何一个队友排队,则他会排到长队的队尾。输入每个团队中所有队员的编号,要求支持如下3种指令(前两种指令可以穿插进行)。
ENQUEUE:编号为X的人进入长队。
DEQUEUE:长队队首出队。
STOP:停止模拟。
对于每个DEQUEUE指令,输出出队的人的编号。

输入:

输入文件中有一组或多组测试数据。
每组测试数据开始有t个团队。下面t行,每行的第一个数字代表这个团队人数,后面是这几个人的编号。编号为0到999999之间的一个整数。
每组测试数据以“STOP”结束。
输入以t==0时结束。
警告:一个测试用例可能包含最多200000(二十万)个命令,所以实现
团队的队列应该是有效的。

输出:

对于每组测试数据,先打印一句"Scenario #k",k是第几组数据。对于每一个"DEQUEUE"指令,输出一个出队的人的编号。每组测试数据后要换行,即使是最后一组测试数据。

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

题目分析:

合适的数据结构可以简化算法,使代码事半功倍

数据结构:
本题排序的原则是按照团体排序,在每个团体内部按照入队的先后顺序排序。
故我们可以给团体的顺序一个队列,再给每个团体内部成员的顺序一个队列。
算法设计: 模拟;
模块设计: 定义与预处理–读入与初始化–模拟–输出–return 0;

代码:
#include<map>
#include<queue>
#include<vector>
#include<cstdio>
#include<iostream>
using namespace std;

int t,n,i=1,temp;
string order;

int main()
{
	 while(1)
	 {
	 	 scanf("%d",&t);
	 	 if(t==0) break;
	 	 queue<int> q1,q2[1005];     //q1为团队序列,q2为团队内部序列
	 	 map<int,int> number;        //number为成员和团队的对应关系
	 	 for(int i1=1;i1<t+1;i1++)
	 	 {
	 	 	 scanf("%d",&n);
	 	 	 for(int i2=0;i2<n;i2++)
	 	 	 {
	 	 	 	 scanf("%d",&temp);
	 	 		 number[temp]=i1;
			 }
		 }
		 printf("Scenario #%d\n",i);
		 while(1)
		 {
		 	 cin>>order;
		 	 if(order=="STOP") break;
		 	 else if(order=="ENQUEUE"){
		 	 	 cin>>temp;
		 	 	 if(q2[number[temp]].empty()){    //这个团队中没有成员在队列中
		 	 	 	 q1.push(number[temp]);
		 	 	 	 q2[number[temp]].push(temp);
				 }else{
				 	 q2[number[temp]].push(temp);
				 }
			 }else if(order=="DEQUEUE"){          //队首元素出队
			 	 int first=q1.front();
			 	 cout<<q2[first].front()<<endl;
			 	 q2[first].pop();
			 	 if(q2[first].empty()) q1.pop();
			 }
		 }
	 i++;
	 printf("\n");
	 }
	 return 0;
}
细节与要点总结:
  1. 队列的二维定义:queue<int> q[1005];
  2. 在选择队内元素排序的容器时,笔者也进行了几种容器的比较:
    queu< set<int> > s;queue< vector<int> > v;但相对于二维队列,前者每个set内的元素默认按照大小排序,后者无法实现首元素出队的操作,故选择二维队列,或者使用vector< queue<int> >;
更新与2020.7.3
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值