您的位置:首页 > 其它

pat1026Table Tennis (30)

2015-10-04 20:20 197 查看
题意分析:

(1)给出N个人到达乒乓球场的时间以及他们需要打多长时间的球,这些人分为两类:一类是VIP客户,一类是非VIP客户,所有的客户按到来的时间排好队伍等候,一旦出现空的乒乓球台,客户将立即选择编号最小的乒乓球台,每个客户最多不能超过两个小时,求每个客户的等待时间,以及每个乒乓球台一天服务了多少人。

(2)VIP客户与普通客户不同点在于:一旦有VIP桌子空闲,处于等待队列中的最早到达的VIP客户(如果有的话)可以获得使用权,而不管他前面是否有人在等待。

(3)如果没有VIP客户,当VIP卓空闲时,普通客户也可使用。

(4)综上所述,需要维护三个队列:VIP客户到达时间的序列、普通用户到达时间的序列、每个桌子空闲的时刻,其中桌子的空闲时刻的计算跟1017题银行窗口空闲时刻的计算一样,大家可以去参考。

(5)这三个队列的更新策略是:一旦有桌子空闲,在队列中最早到达的人可以选择序号最小的空闲的桌子使用;有以下情况例外:若此桌是VIP桌子,且队列中有VIP等待客户,那么无论他前面是否还有等待的人,立即获得使用权;还有若既有普通桌子和VIP桌子空闲,VIP客户选择VIP桌子

可能坑点:

这题难倒了不少人,题干中有几处没有说明白(大坑!!!),其中也是巨坑连连。。。,总结起来有以下几点需要注意:

(1)每个乒乓球台的服务时间在8:00~21:00之间,超过21:00的不再服务

(2)等待队列中,VIP的优先级体现在当有空VIP专用球台时,VIP客户可以直接使用,而不管前面是否有普通客户在等待

(3)最为重要的一点,当有普通球台和VIP球台时,VIP客户遵循选择最小编号的VIP球台(VIP就要这么任性),而非编号最小的球台;普通客户遵循选择最小的球台

(4)每个人的服务时间在2小时之内,超过2小时的按2小时处理;

(5)注意最后计算等待时间时采用的是四舍五入

#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <limits.h>
using namespace std;

struct players
{
int arriveTime;
int startServe;
int serveTime;
int waitTime;
int isVIP;
};
//等待队列中的VIP客户
vector<players >vipPlayers;
//普通客户
vector<players >ordinaryPlayers;
//处理完输出信息的客户
vector<players >total;
struct tables
{
int VIP;
int cnt;
int vacantTime;
};
tables t[101];

bool cmpPlayers(players a,players b)
{
return a.arriveTime<b.arriveTime;
}

bool cmpStartServe(players a,players b)
{
return a.startServe<b.startServe;
}

int main()
{
int N,K,M,i=0;
cin>>N;
int hh,mm,ss,wait,vip;
players temp;
while(i<N)
{
scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&wait,&vip);
temp.arriveTime=hh*3600+mm*60+ss;
temp.serveTime=wait*60;
temp.isVIP=vip;
i++;
if(temp.arriveTime>=3600*21)continue;
if(vip==1)vipPlayers.push_back(temp);
else ordinaryPlayers.push_back(temp);
}
cin>>K>>M;
for(int j=1;j<=K;j++)
{
t[j].VIP=0;
t[j].vacantTime=8*3600;
t[j].cnt=0;
}
int tag;
for(int j=0;j<M;j++)
{
cin>>tag;
t[tag].VIP=1;
}

if(ordinaryPlayers.size()>0)sort(ordinaryPlayers.begin(),ordinaryPlayers.end(),cmpPlayers);
if(vipPlayers.size()>0)sort(vipPlayers.begin(),vipPlayers.end(),cmpPlayers);

while(ordinaryPlayers.size()>0||vipPlayers.size()>0)
{
int minVacant=INT_MAX;
int minVipVacant=INT_MAX;
int index;
int vipIndex;
for(int j=1;j<=K;j++)
{
if(t[j].vacantTime<minVacant)
{
minVacant=t[j].vacantTime;
index=j;
}
if(t[j].VIP==1&&t[j].vacantTime<minVipVacant)
{
minVipVacant=t[j].vacantTime;
vipIndex=j;
}
}
if(t[index].vacantTime>=21*3600)break;
players nextPlayers;
if(vipPlayers.size()==0)
{
nextPlayers=ordinaryPlayers.front();
ordinaryPlayers.erase(ordinaryPlayers.begin());
}
else if(ordinaryPlayers.size()==0)
{
nextPlayers=vipPlayers.front();
vipPlayers.erase(vipPlayers.begin());
}
else
{
if(t[index].VIP==1)
{
if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime||t[index].vacantTime>=vipPlayers.front().arriveTime)
{
nextPlayers=vipPlayers.front();
vipPlayers.erase(vipPlayers.begin());
}
else
{
nextPlayers=ordinaryPlayers.front();
ordinaryPlayers.erase(ordinaryPlayers.begin());
}
}
else
{
if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime)
{
nextPlayers=vipPlayers.front();
vipPlayers.erase(vipPlayers.begin());
}
else
{
nextPlayers=ordinaryPlayers.front();
ordinaryPlayers.erase(ordinaryPlayers.begin());
}
}
}
//控制每个人的时间在两小时之内,超过两小时按两个小时截断
if(nextPlayers.serveTime>7200)nextPlayers.serveTime=7200;
//这里需要记清楚:一旦有VIP桌子空闲,等待队列中的VIP客户就会选择VIP桌子,不管是否有普通桌子空闲
if(nextPlayers.isVIP==1&&nextPlayers.arriveTime>=t[vipIndex].vacantTime)
{
nextPlayers.waitTime=0;
nextPlayers.startServe=nextPlayers.arriveTime;
t[vipIndex].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
t[vipIndex].cnt++;
}
else
{
if(nextPlayers.arriveTime<=t[index].vacantTime)
{
nextPlayers.waitTime=t[index].vacantTime-nextPlayers.arriveTime;
nextPlayers.startServe=t[index].vacantTime;
t[index].vacantTime+=nextPlayers.serveTime;
}
else
{
nextPlayers.waitTime=0;
nextPlayers.startServe=nextPlayers.arriveTime;
t[index].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
}
t[index].cnt++;
}
total.push_back(nextPlayers);
}
sort(total.begin(),total.end(),cmpStartServe);
for(int i=0;i<total.size();i++)
{
int waitMinutes=total[i].waitTime/60+(total[i].waitTime%60<30?0:1);
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",total[i].arriveTime/3600,
(total[i].arriveTime%3600)/60,total[i].arriveTime%60,
total[i].startServe/3600,(total[i].startServe%3600)/60,
total[i].startServe%60,waitMinutes);
}
int first=1;
for(int i=1;i<=K;i++)
{
if(first)first=0;
else cout<<" ";
cout<<t[i].cnt;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: