【PAT】1026. Table Tennis (30) (待改进)

A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.

Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.

One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the priviledge to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (<=10000) - the total number of pairs of players. Then N lines follow, each contains 2 times and a VIP tag: HH:MM:SS - the arriving time, P - the playing time in minutes of a pair of players, and tag - which is 1 if they hold a VIP card, or 0 if not. It is guaranteed that the arriving time is between 08:00:00 and 21:00:00 while the club is open. It is assumed that no two customers arrives at the same time. Following the players' info, there are 2 positive integers: K (<=100) - the number of tables, and M (< K) - the number of VIP tables. The last line contains M table numbers.

Output Specification:

For each test case, first print the arriving time, serving time and the waiting time for each pair of players in the format shown by the sample. Then print in a line the number of players served by each table. Notice that the output must be listed in chronological order of the serving time. The waiting time must be rounded up to an integer minute(s). If one cannot get a table before the closing time, their information must NOT be printed.

Sample Input:
9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 1
2
Sample Output:
08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:12:00 08:16:30 5
08:10:00 08:20:00 10
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0

3 3 2

注意点:

(1)每个人使用桌子的时间不能超过2小时;

(2)如果空出来的桌子是VIP桌子,就要看下队伍中是否有VIP玩家,如果有,则VIP玩家可以插队;

(3)如果空出来的桌子是VIP桌子,但是队伍中没有VIP玩家,则普通玩家可以用这个VIP桌子;

(4)如果空出来的不是VIP桌子,但是队伍中的第一个玩家却是VIP玩家,则该VIP玩家也可以用这普通的桌子;

应该还有其他注意点,我的代码有两组无法通过,待改进:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;

struct node{
	node(){}
	node(int _id, int _h,int _m, int _s, int _playTime, int _vip){
		id = _id;  h = _h;  m = _m; s = _s;
		playTime = _playTime;  vip = _vip;
	}
	int id, playTime, vip;
	int h, m, s; //到达时间 
};

struct tableNode{
	int id, vip, serveCnt, h, m, s;
	tableNode(){
		h=8; m=0; s=0; vip=0; serveCnt=0;
	}
	bool operator < (const tableNode &b)const{
		long timeA = h*3600+ m*60+ s;
		long timeB = b.h*3600+b.m*60+b.s;
		if(timeA > timeB){
			return true;
		}else if(timeA==timeB && id>b.id){
			return true;
		}else{
			return false;
		}
	}
};

struct result{
	int arriveH, arriveM, arriveS;//到达时间 
	int serveH, serveM, serveS; //接收服务的时间 
	int waitTime; //等待时间 
};
 
bool cmp(node a, node b){
	long timeA = a.h*3600+a.m*60+a.s;
	long timeB = b.h*3600+b.m*60+b.s;
    return timeA<timeB;
}

bool cmp1(tableNode a, tableNode b){
	return a.id<b.id;
}

bool cmpByServeTime(result a, result b){
	long ta = a.serveH*3600+a.serveM*60+a.serveS;
	long tb = b.serveH*3600+b.serveM*60+b.serveS;
	if(ta != tb){
		return ta<tb;
	}else{
		return a.serveH*3600+a.serveM*60+a.serveS < b.serveH*3600+b.serveM*60+b.serveS;
	}
}

int main(int argc, char** argv) {
	int n, i, h, m, s, playTime, vip;
	scanf("%d",&n);//pairs of players
	vector<node> player, vips; 
	for(i=0; i<n; i++){
		scanf("%d:%d:%d %d %d", &h,&m,&s,&playTime,&vip);
		if(playTime>120) playTime = 120; //最多只能玩2小时 
		node tmpNode(i,h,m,s,playTime,vip);
		player.push_back(tmpNode);
		if(vip==1) 	vips.push_back(tmpNode);
	}
	sort(player.begin(), player.end(), cmp); //按照到达的时间先后进行排序 	
	sort(vips.begin(), vips.end(),cmp);
	vector<bool> visited(n,false);  //标记该player是否已经安排过了 
	
	int tableNum, vipTable, tableIndex;
	scanf("%d%d",&tableNum, &vipTable); //总桌子数,vip桌子数 
	priority_queue<tableNode> tables;
	set<int> ss;
	for(i=0; i<vipTable; i++){
		cin>>tableIndex;//vip桌子的编号 
		ss.insert(tableIndex);
	}
	
	for(i=0; i<tableNum; i++){
		tableNode t;
		t.id = i+1; //table的id范围是1-N 
		if(ss.count(t.id)>0) t.vip = 1; 
		tables.push(t);
	}
	
 	vector<result> vec;
	for(i=0; i<n; i++){
		node p = player[i];//队伍的第一个人 
		if(visited[p.id]) 
		    continue; //如果已经访问过了,就下一个		
		tableNode t = tables.top();
		tables.pop(); 		
		long tableTime = t.h*3600 + t.m*60 + t.s; //这张table空闲出来的时间 
		long frontTime = p.h*3600 + p.m*60 + p.s; //此时队伍第一个人的到达时间 
		if( tableTime>=21*3600 || frontTime>=21*3600){
		   tables.push(t);
		   break;
		} 		
		long vipTime;//VIP客户中排在第一个的时间	 
		bool findVip = false;
		node v;
		for(vector<node>::iterator it=vips.begin(); it!=vips.end(); it++){
			if(visited[(*it).id]){
				vips.erase(it);	
			}else{
				v = *it;	
				findVip = true;
				break;				
			}	
		}			
		if(findVip) 
		  vipTime = v.h*3600 + v.m*60 + v.s;	 
	 
		result r;
		if( t.vip==1 && findVip && (vipTime<=tableTime)){
			i--;
			visited[v.id] = true;
			playTime = v.playTime;
			r.waitTime = (tableTime-vipTime+30)/60;
			r.arriveH=v.h; r.arriveM=v.m; r.arriveS=v.s;
			r.serveH=t.h; r.serveM=t.m; r.serveS=t.s;
		}else{
		    visited[p.id] = true;
		   	playTime = p.playTime;
		   if(frontTime>=tableTime){
		   		r.waitTime=0;
		   		r.arriveH = r.serveH = p.h;
				r.arriveM = r.serveM = p.m; 
				r.arriveS = r.serveS = p.s;	
				t.s = r.arriveS;	   
		   }else{
		   		r.waitTime = (tableTime-frontTime+30)/60 ;
		   		r.arriveH=p.h; r.arriveM=p.m; r.arriveS=p.s;
		   		r.serveH=t.h; r.serveM=t.m; r.serveS=t.s;	
		   }												
		}
		vec.push_back(r);
		t.m = (r.serveM+playTime)%60;
		t.h = r.serveH + (r.serveM+playTime)/60;
		t.serveCnt++;
		tables.push(t); //插入桌子队伍中,重新按照规则排队 
	}	
	sort(vec.begin(), vec.end(), cmpByServeTime);//根据服务时间先后进行排序输出 
	for(i=0; i<vec.size(); i++){
		result tmp = vec[i];
		printf("%02d:%02d:%02d ",tmp.arriveH, tmp.arriveM, tmp.arriveS);
		printf("%02d:%02d:%02d ", tmp.serveH, tmp.serveM, tmp.serveS);
		printf("%d\n",tmp.waitTime);
	}
	
 	vector<tableNode> vTmp;
 	while(!tables.empty()){
 		vTmp.push_back(tables.top());
 		tables.pop();
	}	
	sort(vTmp.begin(), vTmp.end(), cmp1);//根据桌子的id排序 
	for(i=0; i<vTmp.size(); i++){
		if(i==vTmp.size()-1)
		 	printf("%d\n",vTmp[i].serveCnt);
		else
		 	printf("%d ",vTmp[i].serveCnt);
	}	
	return 0; 
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值