#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int K = 110;
const int INF = 1e9;
struct player
{
int arrival, start, train;
bool isvip;
}newplayer;
struct table
{
int endtime, servenum;
bool isvip;
}tab[K];
vector<player>v;
int change(int h, int m, int s) { return h * 3600 + m * 60 + s; }
bool cmp1(player a, player b) { return a.arrival < b.arrival; }
bool cmp2(player a, player b) { return a.start < b.start; }
int nextvip(int vip)
{
vip++;
while (vip < v.size() && v[vip].isvip == 0) { vip++; }
return vip;
}
void allocate(int idx, int id)
{
v[id].start = max(tab[idx].endtime, v[id].arrival);
tab[idx].endtime = v[id].start + v[id].train;
tab[idx].servenum++;
}
int main()
{
int n, k, m,viptab;
scanf("%d", &n);
int sttime = change(8, 0, 0);
int edtime = change(21, 0, 0);
for (int i = 0; i < n; i++)
{
int h, m, s, train, isvip;
scanf("%d:%d:%d %d %d", &h, &m, &s, &train, &isvip);
newplayer.arrival = change(h, m, s);
newplayer.start = edtime;//初始化为21点
if (newplayer.arrival >= edtime) continue;
newplayer.train = train <= 120 ? train*60 : 7200;
newplayer.isvip = isvip;
v.push_back(newplayer);
}
scanf("%d%d", &k, &m);
for (int i = 1; i <= k; i++) { tab[i].endtime = sttime; tab[i].servenum = tab[i].isvip = 0; }
for (int i = 0; i < m; i++) { scanf("%d", &viptab); tab[viptab].isvip = 1; }
sort(v.begin(), v.end(), cmp1);
int i = 0, vipi = -1;
vipi = nextvip(vipi);//vipi指向当前队列的第一个vip
while (i < v.size())
{
int idx, minend = INF;//最早空闲桌号和时间
for (int j = 1; j <= k; j++)
{
if (tab[j].endtime < minend)
{
minend = tab[j].endtime;
idx = j;
}
}
if (tab[idx].endtime >= edtime) break;//最早空闲的结束时间长于营业时间,直接break
if (v[i].isvip == 1 && i < vipi)
{
i++;
continue;
}
//按照球桌球员分类
if (tab[idx].isvip == 1)//vip球桌
{
if (v[i].isvip == 1)//vip球员
{
allocate(idx, i);
vipi = nextvip(vipi);
i++;
}
else//非vip球员
{
if (vipi<v.size()&&v[vipi].arrival <= tab[idx].endtime)//存在vip在等,注意控制vipi要小于size
{
allocate(idx, vipi);
vipi = nextvip(vipi);
}
else//不存在vip在等
{
allocate(idx, i);
i++;
}
}
}
else//不是vip球桌,这里要注意一点:如果存在多台空闲球桌,vip球员会优先选择空闲的VIP球桌而不是普通球桌
{
if (v[i].isvip == 0)
{
allocate(idx, i);
i++;
}
else//球员是vip
{
int mintime=INF,vipidx=-1;
for (int j = 1; j <= k; j++)
{
if (tab[j].isvip == 1 && tab[j].endtime < mintime)
{
mintime = tab[j].endtime;
vipidx = j;
}
}
if (v[i].arrival >= tab[vipidx].endtime&&vipidx != -1)
{
allocate(vipidx, i);
vipi = nextvip(vipi);
i++;
}
else
{
allocate(idx, i);
vipi = nextvip(vipi);
i++;
}
}
}
}
sort(v.begin(), v.end(), cmp2);
for (int i = 0; i < v.size() && v[i].start < edtime; i++)
{
int t1 = v[i].arrival;
int t2 = v[i].start;
printf("%02d:%02d:%02d ", t1 / 3600, t1 % 3600 / 60, t1 % 60);
printf("%02d:%02d:%02d ", t2 / 3600, t2 % 3600 / 60, t2 % 60);
printf("%.0f\n", round((t2 - t1) / 60.0));
}
for (int i = 1; i <= k; i++)
{
printf("%d", tab[i].servenum);
if (i < k)printf(" ");
}
return 0;
}
A1026 Table Tennis (30 分)
最新推荐文章于 2020-01-16 18:06:28 发布