POJ 2259 Team Queue

题目大意:

         队列和优先队列在计算机科学界耳熟能详,但组队列并没那么有名,但它经常出现在日常生活中,比如在餐厅里面排队买饭的队列就是。

         在一个组队列中,每个元素都属于某一组,在入队时会先找熟人(即同组组员),若有则直接插到同组人的末尾(相当于队列中的队列),若无则只能排到整个队列的末尾了同时他将成为他所属的组中第一个出现在组队列中的成员。对于出队列,就和普通的队列一样了,按照从头到尾的方向逐个出队列。

         现编程实现如下组队列:

         共有多个测例(测例数无上限),每个测例中,以一个整数t作为开头,表示该测例中总共有多少个组(t ≤ 1000),接下来有t行输入,每行都表示一个组,每行以一个整数n开头,表示该组中有多少个成员,接下来就是n个成员的值。(每组最多包含1000个成员,每个成员的值都为大于0的整数(都在int范围内))

         接下来就是一连串的命令,总共有三种命令:

                 ENQUEUE x:将成员x入队

                 DEQUEUE:出队一次

                 STOP:结束此次测例

          以t等于0作为程序终止,由于命令输入量庞大(高达200,000),所以实现一定要高效,入队和出队操作都必须是常数时间的。

题目链接

注释代码:

/*       
 * Problem ID : POJ 2259 Team Queue
 * Author     : Lirx.t.Una       
 * Language   : G++      
 * Run Time   : 391 ms       
 * Run Memory : 3240 KB       
*/   
 
#pragma G++ optimize("O2")

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>

//maximum number of team,最大组数
#define	MAXTEAMN		1000
//最长的命令式ENQUEUE(7个字符),最后一位留给空字符
#define	MAXCMDLEN		8

using namespace std;

queue<int>		team[MAXTEAMN];//用队列表示组,team[i]表示第i号组
char			cmd[MAXCMDLEN];
bool			in[MAXTEAMN];//in[i]表示第i号组是否出现在组队列中

int
main() {

	int		iscn;
	int		t;//组数
	int		n;//每组中组员个数
	int		elem;//element,用于接收成员
	int		i;//计数变量
	int		etm;//element's team number,临时成员所属的组号

	map<int, int>	etotm;//element to team number,建立成员到所属组号的映射

	iscn = 0;
	while ( scanf("%d", &t), t ) {
	
		queue<int>		tmqu;//team queue,组队列,成员为组号

		//每个测例初始化时组队列都为空,因此需要将所有组都记为不在组队列中
		memset(in, false, t * sizeof(bool));
		for ( i = 0; i < t; i++ ) {
		
			scanf("%d", &n);
			while ( n-- ) {
			
				scanf("%d", &elem);
				etotm[elem] = i;//每接收一个成员,都需要标记其所属的组号
			}
		}
		
		printf("Scenario #%d\n", ++iscn);
		while ( scanf("%s", cmd), *cmd != 'S' )
			switch ( *cmd ) {
		
				case 'E' ://若为入队

					scanf("%d", &elem);
					etm = etotm[elem];//先得到其所属的组号
					team[etm].push(elem);//现加入到其组内

					if ( !in[etm] ) {//若在加入组队列之前,其中没有该组成员
					
						tmqu.push(etm);//则需将其组号加入组队列中
						in[etm] = true;//并更新标记
					}

					break;

				default ://若为出队

					etm = tmqu.front();//现获得组队列首部的组号
					printf("%d\n", team[etm].front());//根据组号打印该组的首个元素
					team[etm].pop();//输出后将该成员出队

					if ( team[etm].empty() ) {//若弹出的成员为该组的最后一个成员

						tmqu.pop();//则需将该组号从组队列中出队
						in[etm] = false;//并更新标记
					}

					break;
			}

		putchar('\n');
		
		for ( i = 0; i < t; i++ )//将各组清空后进入下一测例
			while ( !team[i].empty() )
				team[i].pop();
	}
	
	return 0;
}
无注释代码:

#pragma G++ optimize("O2")

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>

#define	MAXTEAMN		1000
#define	MAXCMDLEN		8

using namespace std;

queue<int>		team[MAXTEAMN];
char			cmd[MAXCMDLEN];
bool			in[MAXTEAMN];

int
main() {

	int		iscn;
	int		t;
	int		n;
	int		elem;
	int		i;
	int		etm;

	map<int, int>	etotm;

	iscn = 0;
	while ( scanf("%d", &t), t ) {
	
		queue<int>		tmqu;

		memset(in, false, t * sizeof(bool));
		for ( i = 0; i < t; i++ ) {
		
			scanf("%d", &n);
			while ( n-- ) {
			
				scanf("%d", &elem);
				etotm[elem] = i;
			}
		}
		
		printf("Scenario #%d\n", ++iscn);
		while ( scanf("%s", cmd), *cmd != 'S' )
			switch ( *cmd ) {
		
				case 'E' :

					scanf("%d", &elem);
					etm = etotm[elem];
					team[etm].push(elem);

					if ( !in[etm] ) {
					
						tmqu.push(etm);
						in[etm] = true;
					}

					break;

				default :

					etm = tmqu.front();
					printf("%d\n", team[etm].front());
					team[etm].pop();

					if ( team[etm].empty() ) {

						tmqu.pop();
						in[etm] = false;
					}

					break;
			}

		putchar('\n');

		for ( i = 0; i < t; i++ )
			while ( !team[i].empty() )
				team[i].pop();
	}
	
	return 0;
}

单词解释:

priority:n, 优先,优先权

mensa:n, 学生食堂

dequeue:vi, 出列

enqueue:vi, 入队

process:vt, 处理,加工

simulate:vt, 模拟

terminate:vt, 终止

implementation:n, 实现,履行


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值