1026.Table Tennis

来源:互联网 发布:人力资源责任矩阵图 编辑:程序博客网 时间:2024/05/22 07:09
【题意】
        一个乒乓球馆有若干球桌,分为普通球桌和VIP球桌,若有VIP球桌空着且有VIP球员在等待,则将VIP球桌优先分给VIP球员;若有VIP球员在等但没有空着的VIP球桌,则VIP球员和其他球员按照先到先得的方式得到剩余球桌使用权;若无VIP球员等待,则普通球员也可使用VIP球桌,普通球员选球桌仅仅按照编号由小到大的顺序选。
        最后输出打上球的球员们的入场时间、开始打球时间以及等待时间,并输出每个球桌有多少对球员打过球。

【思路】
        和银行柜台的问题类似(1014、1017),只不过这次有了VIP球员和VIP球桌,使得球桌的分配要考虑的情况变多了。这里需要建立两个等待队列,分别排着普通球员和VIP球员。
        总的思路还是模拟时间的推进,不过要注意的是每次分配球桌首先要将等待的VIP球员尽可能地分到VIP球桌上,剩下的就是公平竞争球桌,即和之前的银行柜台问题一样了。

【注意点】
        1.    等待时间需要四舍五入,方法是(int)(a+0.5),其中a是浮点数。秒到分的话就是((second+30)/60),这里second是整数;
        2.    这道题中一对选手最多只能玩2小时是一个卡分点,不像之前银行问题中“保证少于多少时间”,这里的说法是“假定两个选手最多能玩2小时”,于是这个就不算是默认条件了= =,在读入的时候碰上playing time超过120min的直接砍到120min即可;
        3.    在读取队列队首之前记得要判断队列是否为空,否则可能会出段错误;
        4.    到最后一直有一个1分的点过不去,结果发现是我一开始的代码里没有先对所有等待的VIP球员进行处理,而是在对每个球桌的分配时再处理,这样虽然不知道错在哪,但改了就过了。。。不管怎么说先尽量分配VIP球桌给VIP球员这种写法代码简洁了一些,思路上也更清晰,还是更说得通一点的。

#include <iostream>#include <cstring>#include <cstdio>#include <queue>#include <algorithm>using namespace std;#define MAX_TABLE_NUM 100typedef struct{int arriveTime[3];//hh:mm:ssint at;int servedTime[3];//hh:mm:ssint st;int playingTime;bool vip;}player;bool cmpArrive(player p1, player p2){return p1.at<p2.at;}bool cmpServe(player p1, player p2){return (p1.st<p2.st)||(p1.st==p2.st && p1.at<p2.at);}int main(int argc, char const *argv[]){queue<player> tables[MAX_TABLE_NUM];queue<player> waitOrdinary,waitVip;vector<player> players;vector<player> servedPlayers;vector<int> vipTables;int n,k,m,served[MAX_TABLE_NUM];bool vipSignal[MAX_TABLE_NUM];memset(served,0,sizeof(served));memset(vipSignal,0,sizeof(vipSignal));cin >> n;for(int i=0; i<n; i++){player tmp;scanf("%d:%d:%d %d %d", &tmp.arriveTime[0], &tmp.arriveTime[1], &tmp.arriveTime[2], &tmp.playingTime, &tmp.vip);tmp.at = tmp.arriveTime[0]*3600+tmp.arriveTime[1]*60+tmp.arriveTime[2];if(tmp.arriveTime[0]>=21){continue;}if(tmp.playingTime>120){tmp.playingTime = 120;}tmp.playingTime *= 60;players.push_back(tmp);}cin >> k >> m;int index;for(int i=0; i<m; i++){cin >> index;vipSignal[index-1] = 1;vipTables.push_back(index-1);}sort(vipTables.begin(),vipTables.end());sort(players.begin(), players.end(), cmpArrive);for(vector<player>::iterator it = players.begin(); it != players.end(); ++it){if((*it).vip){waitVip.push(*it);}else{waitOrdinary.push(*it);}}players.clear();int startTime = 8*3600;int endTime = 21*3600;int currentTime = startTime;while(currentTime<endTime){int passTime = endTime-currentTime;//先把所有等待的VIP分配到可分配的VIP桌上while(!waitVip.empty() && waitVip.front().at<=currentTime){vector<int>::iterator it;for(it=vipTables.begin(); it!=vipTables.end(); it++){if(tables[*it].empty()){waitVip.front().st = currentTime;tables[*it].push(waitVip.front());served[*it]++;waitVip.pop();if(tables[*it].front().playingTime<passTime){passTime = tables[*it].front().playingTime;}break;}}if(it==vipTables.end()){break;}}for(int index=0; index<k; index++){if(!tables[index].empty()){if(tables[index].front().playingTime<passTime){passTime = tables[index].front().playingTime;}}else{//普通球员和VIP球员都没有在等待的if(!(!waitOrdinary.empty() && waitOrdinary.front().at<=currentTime) && !(!waitVip.empty() && waitVip.front().at<=currentTime)){if(!waitOrdinary.empty() && waitOrdinary.front().at-currentTime<passTime){passTime = waitOrdinary.front().at-currentTime;}if(!waitVip.empty() && waitVip.front().at-currentTime<passTime){passTime = waitVip.front().at-currentTime;}}//只有普通球员在等待else if(!waitOrdinary.empty() && waitOrdinary.front().at<=currentTime && !(!waitVip.empty() && waitVip.front().at<=currentTime)){waitOrdinary.front().st = currentTime;tables[index].push(waitOrdinary.front());served[index]++;waitOrdinary.pop();if(tables[index].front().playingTime<passTime){passTime = tables[index].front().playingTime;}}//只有VIP球员在等待else if(!(!waitOrdinary.empty() && waitOrdinary.front().at<=currentTime) && !waitVip.empty() && waitVip.front().at<=currentTime){waitVip.front().st = currentTime;tables[index].push(waitVip.front());served[index]++;waitVip.pop();if(tables[index].front().playingTime<passTime){passTime = tables[index].front().playingTime;}}else{//普通球员和VIP球员都在等//VIP桌子不够分,公平竞争if(waitOrdinary.front().at<waitVip.front().at){waitOrdinary.front().st = currentTime;tables[index].push(waitOrdinary.front());waitOrdinary.pop();}else{waitVip.front().st = currentTime;tables[index].push(waitVip.front());waitVip.pop();}served[index]++;if(tables[index].front().playingTime<passTime){passTime = tables[index].front().playingTime;}}}}//for(int index=0; index<k; index++)currentTime += passTime;for(int index=0; index<k; index++){if(!tables[index].empty()){tables[index].front().playingTime -= passTime;if(tables[index].front().playingTime==0){servedPlayers.push_back(tables[index].front());tables[index].pop();}}}}for(int index=0; index<k; index++){if(!tables[index].empty()){servedPlayers.push_back(tables[index].front());tables[index].pop();}}sort(servedPlayers.begin(),servedPlayers.end(),cmpServe);for(vector<player>::iterator it=servedPlayers.begin(); it!=servedPlayers.end(); it++){(*it).servedTime[0] = (*it).st/3600;(*it).servedTime[1] = ((*it).st%3600)/60;(*it).servedTime[2] = (*it).st%60;printf("%02d:%02d:%02d ", (*it).arriveTime[0], (*it).arriveTime[1], (*it).arriveTime[2]);printf("%02d:%02d:%02d ", (*it).servedTime[0], (*it).servedTime[1], (*it).servedTime[2]);cout << ((*it).st-(*it).at+30)/60 << endl;}for(int i=0; i<k; i++){cout << served[i];if(i!=k-1){cout << " ";}}system("pause");return 0;}


0 0