思路:
用两个队列,vip队列和普通队列,
找到完成时间最早的窗口,如果比两个队列最早的人的到达时间还早,就更新窗口完成时间为两者最小值,然后回到开头重新找完成时间最早的窗口;
若选中vip队列,则重新查找窗口,优先选 vip 窗口;
若选中普通队列,则使用该窗口;
注意:
- vip玩家,优先分配vip桌子
- 等待时间大于等于30秒,进一分钟,小于30秒则舍去的原则;
- 游戏时长不能超过 120 分钟
1026 Table Tennis (30 point(s))
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.
Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.
One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the privilege to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.
Example:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#include<vector>
using namespace std;
int Stamp(string s)
{
int HH, MM, SS;
sscanf(s.c_str(), "%d:%d:%d", &HH, &MM, &SS);
return HH*3600+MM*60+SS;
}
string Time(int stamp)
{
string s;
char str[12];
int HH = stamp / 3600, MM = stamp % 3600 / 60, SS = stamp % 3600 % 60;
sprintf(str, "%02d:%02d:%02d", HH, MM, SS);
return string(str);
}
struct table {
int count;
int finish;
int vip;
bool operator<(const table &rhs) const {
return finish < rhs.finish;
}
};
int main()
{
int N;
cin >> N;
map<string, int> Member;
map<string, int> Vip;
for(int i = 0; i < N; i++) {
string arrive;
int serve, vip;
cin >> arrive >> serve >> vip;
if(serve > 120) serve = 120;
if(vip == 1) Vip[arrive] = serve;
else Member[arrive] = serve;
}
int K, M;
cin >> K >> M;
vector<table> Win(K);
for(int i = 0; i < M; i++) {
int v;
cin >> v;
Win[v-1].vip = 1;
}
for(int i = 0; i < N;) {
auto it = min_element(Win.begin(), Win.end());
if(it->finish >= Stamp("21:00:00")) break;
map<string, int> *p;
if(Vip.empty()) {
int normStamp = Stamp(Member.begin()->first);
if(it->finish < normStamp) {
it->finish = normStamp;
continue;
}
p = &Member;
} else if(Member.empty()) {
int vipStamp = Stamp(Vip.begin()->first);
if(it->finish < vipStamp) {
it->finish = vipStamp;
continue;
}
p = &Vip;
} else {
int vipStamp = Stamp(Vip.begin()->first);
int normStamp = Stamp(Member.begin()->first);
if(it->finish < min(vipStamp, normStamp)) {
it->finish = min(vipStamp, normStamp);
continue;
}
if(vipStamp <= normStamp) p = &Vip;
else if(it->vip == 1 && vipStamp <= it->finish) p = &Vip;
else p = &Member;
}
string time = p->begin()->first;
int stamp = Stamp(time);
if(p == &Vip)
for(auto t = Win.begin(); t != Win.end(); t++)
if(t->vip && t->finish <= stamp) { it = t; break; }
int wait = it->finish - stamp;
if(wait % 60 >= 30) wait = wait + 60;
wait = wait / 60;
cout << time << ' ' << Time(it->finish) << ' ' << wait << endl;
it->finish += (*p)[time] * 60;
(*p).erase(time);
i++, it->count++;
}
for(int i = 0; i < K; i++) cout << (i==0 ? "" : " ") << Win[i].count;
}