您的位置:首页 > 其它

1026.Table Tennis

2015-01-13 14:10 106 查看
【题意】
一个乒乓球馆有若干球桌,分为普通球桌和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 100

typedef struct{
int arriveTime[3];//hh:mm:ss
int at;
int servedTime[3];//hh:mm:ss
int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: