地址:https://pintia.cn/problem-sets/994805342720868352/problems/994805472333250560
pat的模拟是又坑又难写,不想写模拟,老出坑;
所以网上查了一下,别人写的代码较少的模拟;
坑点:
(1)每个乒乓球台的服务时间在8:00~21:00之间,超过21:00的不再服务
(2)等待队列中,VIP的优先级体现在当有空VIP专用球台时,VIP客户可以直接使用,而不管前面是否有普通客户在等待
(3)最为重要的一点,当有普通球台和VIP球台时,VIP客户遵循选择最小编号的VIP球台(VIP就要这么任性),而非编号最小的球台;普通客户遵循选择最小的球台
(4)每个人的服务时间在2小时之内,超过2小时的按2小时处理;
(5)注意最后计算等待时间时采用的是四舍五入
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
//存储每个节点的到达时间,等待时间,客户等级
struct Node{
int time,last,f;
}p[10005];
//存储到达时间,服务时间,等待时间长度
struct result{
int t1,t2,wait;
}res[10005];
vector<Node>v[2]; //存储不同等级客户的情况
int ok[105],vip[105],serve[105];
int n,m,k;
bool cmp(const Node &p,const Node &q){
return p.time < q.time;
}
bool cmp1(const result &p,const result &q){
return p.t2 < q.t2;
}
//根据客户等级找到对应的桌子
int Find(int tm,int f)
{
int MIN = inf,ans = 0;
for(int i = 1;i <= m;++i){
if(f && !vip[i]) continue;
if(ok[i] < tm){
ans = i;
break;
}else if(ok[i] < MIN){
ans = i;
MIN = ok[i];
}
}
return ans;
}
int main()
{
int n;
cin >> n;
for(int i = 0;i < n;++i){
int a,b,c;
scanf("%d:%d:%d %d %d",&a,&b,&c,&p[i].last,&p[i].f);
p[i].time = a * 3600 + b * 60 + c;
if(p[i].f) v[1].pb(p[i]);
else v[0].pb(p[i]);
}
p[n].time = inf;
p[n + 1].time = inf;
v[0].pb(p[n]); v[1].pb(p[n + 1]);
sort(v[0].begin(),v[0].end(),cmp);
sort(v[1].begin(),v[1].end(),cmp);
cin >> m >> k;
//初始化起始时间
for(int i = 1;i <= m;++i){
ok[i] = 8 * 60 * 60;
}
memset(vip,0,sizeof(vip));
for(int i = 1;i <= k;++i){
int a;
cin >> a;
vip[a] = 1;
}
int num = 0;
int i = 0,j = 0;
//每次从v[0],v[1]即普通客户和vip客户中选一个分配,题中已说明同一个时间不会有多个客户到达
//得到vip_table是为了当分配的是vip客户,那么如果ok[vip_table] <= v[1][pos].time,应该优先分配这一桌
//尽管得到的ok[id] <= ok[vip_table]
while(true){
int tm1 = v[0][i].time,tm2 = v[1][j].time;
int id = Find(min(tm1,tm2),0),who;
int vip_table = Find(tm2,1);
//如果找到的桌子的时间在21点之后或者到达时间在21点之后,那么就得就到终点了
if(ok[id] >= 21 * 60 * 60 || min(tm1,tm2) >= 21 * 60 * 60) break;
if(!vip[id]) who = v[0][i].time < v[1][j].time ? 0 : 1;
else who = v[1][j].time < max(ok[id],v[0][i].time) ? 1 : 0;
int pos = who == 0 ? i : j;
if(who == 1 && vip_table && ok[vip_table] <= v[1][pos].time) id = vip_table;
res[num].t1 = v[who][pos].time;
res[num].t2 = max(ok[id],v[who][pos].time);
res[num].wait = res[num].t2 - res[num].t1;
ok[id] = res[num].t2 + min(v[who][pos].last,120) * 60;
serve[id]++;
if(who == 0) i++;
else j++;
num++;
}
sort(res,res + num,cmp1);
for(int i = 0;i < num;++i){
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",res[i].t1/3600,res[i].t1%3600/60,res[i].t1%60,res[i].t2/3600,res[i].t2%3600/60,res[i].t2%60,(res[i].wait+30)/60);
}
for(int i = 1;i < m;++i) cout << serve[i] << " ";
cout << serve[m] << endl;
return 0;
}