PAT A1026

#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
using namespace std;
const int maxn=10010;
const int INF=22*3600;
struct record{
	int atime,stime,ptime,flag;
	record(){
		stime=INF;
	}
}re[maxn];
int N,K,M,vipta[150]={0},table[150]={0},cus[150]={0};
bool isbusy[150]={0};
queue<int> vip,ordinary;
bool cmp1(record a,record b){
	return a.atime<b.atime;
}
bool cmp2(record a,record b){
	return a.stime<b.stime;
}
void selectvip(int nowtime,int i,bool flag){
	if(!vip.empty()&&re[vip.front()].atime<=nowtime){
		re[vip.front()].stime=nowtime; //相应客户的服务时间 
		if(flag) re[vip.front()].ptime++;  //需要多减一次 
		isbusy[vipta[i]]=true;  //修改桌子是否有人,vipta数组表示vip桌的桌号 
		table[vipta[i]]=vip.front(); //桌子所对应的客户号 
		vip.pop();
	}
}
void selectordinary(int nowtime,int i){
	//vip 队列中队首元素的到达时间最短 
	if(!vip.empty()&&re[vip.front()].atime<=nowtime&&(ordinary.empty()||(!ordinary.empty()&&ordinary.front()>vip.front()))){
		re[vip.front()].stime=nowtime; //相应客户的服务时间 
		isbusy[i]=true;  //修改桌子是否有人,vipta数组表示vip桌的桌号 
		table[i]=vip.front(); //桌子所对应的客户号 
		vip.pop();
	}else if(!ordinary.empty()&&re[ordinary.front()].atime<=nowtime&&(vip.empty()||(!vip.empty()&&ordinary.front()<vip.front()))){
		re[ordinary.front()].stime=nowtime; //相应客户的服务时间 
		isbusy[i]=true;  //修改桌子是否有人,vipta数组表示vip桌的桌号 
		table[i]=ordinary.front(); //桌子所对应的客户号 
		ordinary.pop();
	}
}
int main(){
	//freopen("g:\\in.txt","r",stdin);
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		int th,tm,ts;
		scanf("%d:%d:%d%d%d",&th,&tm,&ts,&re[i].ptime,&re[i].flag);
		if(re[i].ptime>=120) re[i].ptime=7200;
		else re[i].ptime*=60;
		re[i].atime=th*3600+tm*60+ts;
	}
	scanf("%d%d",&K,&M);
	for(int i=0;i<M;i++){
		scanf("%d",&vipta[i]);
	}
	sort(re,re+N,cmp1);
	for(int i=0;i<N;i++){
		if(re[i].flag==0) ordinary.push(i);
		else vip.push(i);
	}
	fill(table,table+150,-1);
	int nowtime=8*3600;
	while(nowtime<21*3600){
		for(int i=0;i<M;i++){  //先看vip桌 
			if(!isbusy[vipta[i]]) selectvip(nowtime,i,1); //该桌没人玩 
		}
		for(int i=1;i<=K;i++){
			if(!isbusy[i]){
				selectordinary(nowtime,i);
			}else{
				re[table[i]].ptime--;
				if(re[table[i]].ptime==0){
					cus[i]++;
					isbusy[i]=false;
				}
			}
		}
		for(int i=0;i<M;i++)
			if(re[table[vipta[i]]].ptime==0) selectvip(nowtime,i,0);
		for(int i=1;i<=K;i++)
			if(re[table[i]].ptime==0) selectordinary(nowtime,i);
		nowtime++;
	}
	for(int i=1;i<=K;i++)
		if(re[table[i]].ptime>0) cus[i]++;
	sort(re,re+N,cmp2);
	for(int i=0;i<N;i++){
		if(re[i].stime>=INF) break;
		printf("%02d:%02d:%02d ",re[i].atime/3600,re[i].atime%3600/60,re[i].atime%60);
		printf("%02d:%02d:%02d ",re[i].stime/3600,re[i].stime%3600/60,re[i].stime%60);
		printf("%d\n",(int)round((re[i].stime-re[i].atime)*1.0/60));
	}
	for(int i=1;i<=K;i++)
		i!=K?printf("%d ",cus[i]):printf("%d",cus[i]);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值