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、花了很久才ac的题目之一,万恶的vip们。。。。。。
2、先说一下思路:
     1)在录入顾客的时候将他们分成普通客户和vip客户录入两个vector中(注意playtime>2 hours的要截断),录完之后按照到达的先后顺序排序。
     2)开始循环给每个客户“找桌子”,每次循环处理一个客户
     3)在每个循环中,在普通客户和vip客户中选择最早到达的的客户作为这个循环目前需要处理安排的客户,如果该客户的service time在俱乐部打烊之后,则结束循环
          A)如果这是个坑爹的vip客户
               a)如果这个坑货到的时候有空桌子
                    i)如果这些空桌子中正好有坑爹的vip桌子,选择 编号最小的那个vip桌子给他
                    ii)如果没有vip桌子,则选择 编号最小的那个空桌子给他
               b)如果这个坑货到的时候没有空桌子,就需要等待最早空出的那个桌子(注意可能有多个桌子同时空出来)
                    i)如果最早有空桌子出来的时候有多个空桌子空出来,有vip桌时安排以vip桌,无vip桌则选择 编号最小的那个空桌子
                    ii)如果最早有空桌子出来的时候只有一个空桌子,则选择以该桌
          B)如果这是个善良的普通客户
               a)如果他到的时候有空桌子,则选择 编号最小的那个空桌子给他
               b)如果他到的时候没有空桌子,则需要等待最早空出的那个桌子
                    i)如果不幸的是在有桌子空出来的时候已经有vip客户到达,而且空出来的桌子里面有vip桌,坑爹的vip客户就会毫不留情地插队,该循环就得优先给vip客户安排,可怜的普通用户就只能靠边站了
                    ii)如果不是i)中的情况,可怜的普通用户就可以在有桌子空出来的时候选择 编号最小的那个桌子
     4)以上是每个循环中的处理过程,处理完成之后输出当前处理用户(注意3)->B)->b
)->i)的情况发生时当前处理用户就变成了那个坑爹的vip用户)的各种time,需要十分注意的是输出的waiting time一定是严格的四舍五入,否则最后一个case是无法通过的
3、由于上述过程是严格按照service的先后时间来的,所以不需要再进行排序什么的,直接在每个循环中输出当前客户的信息就可以了,下面的代码里面被注释掉的排序的代码是不需要看的。
4、总之这是一道神坑巨多的题目,我等编程能力巨烂的人需要花很长时间才能找出所有的考察点,不过当程序全部ac的那一刻还是有点小激动的  ^_^

代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
struct customer
{
	int arrTime;//arriving time in second
	int serTime;//serving time in second
	int waiTime;//waiting time in second
	int plaTime;//playing time in second
	int vip;//vip flag
	bool operator < (const customer &c) const
	{
		return arrTime<c.arrTime;
	}
};
vector<customer>ordCus; //ordinary customers vector
vector<customer>vipCus; //vip customers vector
int tabTime[100]={0};//the end of using time of current customer
int isVipTab[100]={0};//isVipTab[i]=1 if the i-th table is for vip
int tabUse[100]={0};//using times of each table
int str2sec(char *t)
{//transform s string in fomat HH:MM:SS to time in seconds
	int time;
	time=((t[0]- '0')*10+t[1]-'0' -8)*3600+((t[3]-'0')*10+t[4]- '0')*60+(t[6]-'0' )*10+t[7]-'0';
	return time;
}
void sec2str(int time,char *t)
{//transform time in seconds to a string in format HH:MM:SS
	t[2]=t[5]= ':';
	t[0]=(time/3600+8)/10+ '0';
	t[1]=(time/3600+8)%10+ '0';
	t[3]=(time%3600)/60/10+ '0';
	t[4]=((time%3600)/60)%10+ '0';
	t[6]=(time%60)/10+ '0';
	t[7]=(time%60)%10+ '0';
	t[8]= '\0';
}

//bool cmp(customer a,customer b)
//{
//        if(a.serTime==b.serTime)
//                 return a.arrTime<b.arrTime;
//        else
//                 return a.serTime<b.serTime;
//}

int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;++i)
	{
		customer c;
		char strTime[10];
		int isvip;
		cin>>strTime;
		c.arrTime=str2sec(strTime);
		cin>>c.plaTime>>c.vip;
		if(c.plaTime>120)//if playing time is more than 120 minutes(2 hours),set it to be 120
			c.plaTime=120;
		c.plaTime*=60; //transform minute to be second
		if(c.vip)//if the customer is vip, push him into vipCus
			vipCus.push_back(c);
		else ordCus.push_back(c);
	}
	if(ordCus.size()>0)
		sort(ordCus.begin(),ordCus.end()); //sort in increasing arriving time
	if(vipCus.size()>0)
		sort(vipCus.begin(),vipCus.end());
	int k,m,v;
	cin>>k>>m;
	for(int i=0;i<m;++i)
	{
		cin>>v;
		isVipTab[v-1]=1; //record vip table
	}
	int ordIndex=0,vipIndex=0;
	int j;
	vector<customer> ans;
	while(ordIndex<ordCus.size() || vipIndex<vipCus.size())
	{
		customer front;
		int tab;//index of table occupied in this loop
		//first find the front customer in the waitting queue
		if(ordIndex==ordCus.size())
			front=vipCus[vipIndex++];
		else if (vipIndex==vipCus.size())
			front=ordCus[ordIndex++];
		else if (vipCus[vipIndex].arrTime<ordCus[ordIndex].arrTime)
			front=vipCus[vipIndex++];
		else front=ordCus[ordIndex++];

		int availTime=tabTime[0],earlist=0;
		vector< int>availTable;//available tables for the front customer
		for(j=0;j<k;++j)
		{ //find the tables which is available for the front customer
			if(tabTime[j]<=front.arrTime)
				availTable.push_back(j);
			if(tabTime[j]<availTime)
			{ //find the table which is earlist available with the smallist number
				earlist=j;
				availTime=tabTime[j];
			}
		}
		//when the earlist table's available time or the front customer's arriving time
		//is later than closing time, break the loop
		if(availTime>=13*3600 || front.arrTime>=13*3600)
			break;
		if(front.vip)
		{ //if the front customer is a vip
			if(availTable.size()>0)
			{ //if there are available tables when arriving
				tab=availTable[0];
				for(j=0;j<availTable.size();++j)
				{ //if there is vip table available, choose the first one
					//if not, still choose availTable[0] the table with the smallest number
					if(isVipTab[availTable[j]])
					{
						tab=availTable[j];
						break;
					}
				}
			}
			else
			{ //if there is no available table when arriving, just wait for the earlist available table
				for(j=0;j<k;++j)
				{ //find all of the available table when the the earlist available table open
					//that means there might be more than one table open at the same time
					if(tabTime[j]<=availTime)
						availTable.push_back(j);
				}
				tab=availTable[0];
				for(j=0;j<availTable.size();++j)
				{ //if there is vip table in all available tables, choose the first one
					//if not, still choose availTable[0] the table with the smallest number
					if(isVipTab[availTable[j]])
					{
						tab=availTable[j];
						break;
					}
				}
			}
		}
		else
		{ //if the front customer is not a vip
			if(availTable.size()>0)
			{ //if there are available tables when arriving, use the table with the smallest number
				tab=availTable[0];
			}
			else
			{ //if there is no available table when arriving, just wait for the earlist available table
				if(!vipCus.empty() && vipCus[vipIndex].arrTime<=availTime)
				{ //if there is vip customer arrived before earlist first table open
					for(j=0;j<k;++j)
					{ //check if there is a vip table open at the available time
						if(tabTime[j]<=availTime && isVipTab[j])
							break;
					}
					if(j!=k)
					{ //if there is vip table open, the vip customer has the previlidge to use it
						tab=j;
						front=vipCus[vipIndex++]; //then vip customer become the front one
						--ordIndex; //the front ordinary customer back off
					}
					else
					{ //if there is no vip table open, ignore the vip customer's previlidge
						tab=earlist;
					}
				}
				else
				{ //if there is no vip customer arrived before earlist first table open
					//choose the earlist open table
					tab=earlist;
				}
			}
		}
		++tabUse[tab]; //count the use time
		front.serTime=max(tabTime[tab],front.arrTime);
		front.waiTime=front.serTime-front.arrTime;
		tabTime[tab]=front.serTime+front.plaTime;
		//ans.push_back(front);
		char arr[10],ser[10];
		sec2str(front.arrTime,arr);
		sec2str(front.serTime,ser);
		//round up to an integer minutes!!!!!!!!!!!!!神??坑??!!!!
		cout<<arr<< ' '<<ser<<' ' <<(front.waiTime+30)/60<<endl;
	}
	//sort(ans.begin(),ans.end(),cmp);
	//for(int i=0;i<ans.size();++i)
	//{
	//        char arr[10],ser[10];
	//        sec2str(ans[i].arrTime,arr);
	//        sec2str(ans[i].serTime,ser);
	//        //round up to an integer minutes!!!!!!!!!!!!!
	//        cout<<arr<<' '<<ser<<' '<<(ans[i].waiTime+30)/60<<endl;
	//}
	cout<<tabUse[0];
	for(int i=1;i<k;++i)
		cout<< ' '<<tabUse[i];
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The following is the data that you can add to your input file (as an example). Notice that the first line is going to be a line representing your own hobbies. In my case, it is the Vitaly,table tennis,chess,hacking line. Your goal is to create a class called Student. Every Student will contain a name (String) and an ArrayList<String> storing hobbies. Then, you will add all those students from the file into an ArrayList<Student>, with each Student having a separate name and ArrayList of hobbies. Here is an example file containing students (the first line will always represent yourself). NOTE: eventually, we will have a different file containing all our real names and hobbies so that we could find out with how many people each of us share the same hobby. Vitaly,table tennis,chess,hacking Sean,cooking,guitar,rainbow six Nolan,gym,piano,reading,video games Jack,cooking,swimming,music Ray,piano,video games,volleyball Emily,crochet,drawing,gardening,tuba,violin Hudson,anime,video games,trumpet Matt,piano,Reading,video games,traveling Alex,swimming,video games,saxophone Roman,piano,dancing,art Teddy,chess,lifting,swimming Sarah,baking,reading,singing,theatre Maya,violin,knitting,reading,billiards Amy,art,gaming,guitar,table tennis Daniel,video games,tennis,soccer,biking,trumpet Derek,cooking,flute,gaming,swimming,table tennis Daisey,video games,guitar,cleaning,drawing,animated shows,reading,shopping Lily,flute,ocarina,video games,baking Stella,roller skating,sudoku,watching baseball,harp Sophie,viola,ukulele,piano,video games
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值