第一次提交WA三个点
测试点3:到达时间刚好为21点的player没有入场机会
测试点4:playing time不能超过两个小时
测试点8:等待时间四舍五入,大于等于30s视为一分钟
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int INF = 1e9 + 7;
const int N = 10000;
const int K = 100;
int n,k,m;
struct node {
int arriveTime;
int playTime;
int serveTime;
int VIP;
};
node po[N + 1];
int table[K + 1];
int busy[K + 1];
int cnt[K + 1];
int cmp(const node& A, const node& B) {
return A.arriveTime < B.arriveTime;
}
int cmp2(const node& A, const node& B) {
return A.serveTime < B.serveTime;
}
int notAvi(int T) {
for (int i = 1; i <= k; ++i) {
if (busy[i] <= T) return 0;
}
return 1;
}
int findVIPTable(int T) {
for (int i = 1; i <= m; ++i) {
if (busy[table[i]] <= T) //avilable VIP table
return table[i];
}
return -1;
}
int findTable(int T) {
//if there is no VIP in the queue, the next pair of players can take it
//if when it is the turn of a VIP pair, yet no VIP table is available,
//they can be assigned as any ordinary players
for (int i = 1; i <= k; ++i) {
if (busy[i] <= T) //avilable table
return i;
}
return -1;
}
int nowServe = 1; //the first can serve player
int canServe = 1; //the last can serve player
void doit(int T) {
if (po[nowServe].arriveTime > T) return; //no player
if (notAvi(T)) return; //no table
while (canServe + 1 <= n && po[canServe + 1].arriveTime <= T) canServe++;
int x;
//VIP waiting in line
while (1) {
int VIP = -1;
for (int i = nowServe; i <= canServe; ++i)
if (po[i].VIP && po[i].serveTime == -1) {
VIP = i; break;
}
x = findVIPTable(T);
if (VIP != -1 && x != -1) {
busy[x] = T + po[VIP].playTime;
po[VIP].serveTime = T;
cnt[x]++;
}
else break;
}
while (1) {
int flag = 0;
for (int i = nowServe; i <= canServe; ++i) {
if (po[i].serveTime == -1) {
nowServe = i;
flag = 1;
break;
}
}
if (!flag) {
nowServe = canServe + 1;
break;
}
x = findTable(T);
if (x != -1) {
busy[x] = T + po[nowServe].playTime;
po[nowServe].serveTime = T;
cnt[x]++;
}
else break;
}
}
void prt(int t) {
int h, m, s;
h = t / 3600;
m = (t % 3600) / 60;
s = t % 60;
if (h <= 9) printf("0%d:", h);
else printf("%d:",h);
if (m <= 9) printf("0%d:", m);
else printf("%d:", m);
if (s <= 9) printf("0%d", s);
else printf("%d", s);
}
void print() {
for (int i = 1; i <= n; ++i) {
//测试点8
if (po[i].serveTime != -1 && po[i].serveTime < 21 * 3600) {
prt(po[i].arriveTime);
printf(" ");
prt(po[i].serveTime);
int x = (po[i].serveTime - po[i].arriveTime) / 60;
//测试点8
if ((po[i].serveTime - po[i].arriveTime) % 60 >= 30) x++;
printf(" %d\n", x);
}
}
for (int i = 1; i <= k; ++i) {
printf("%d",cnt[i]);
if (i != k) printf(" ");
}
}
int main()
{
char c;
scanf("%d",&n);
c=getchar(); //\n
for (int i = 1; i <= n; ++i) {
int h, m, s;
char c1,c2;
c1 = getchar(); c2 = getchar();
h = ((c1 - '0') * 10 + c2 - '0') * 3600;
c = getchar(); //:
c1 = getchar(); c2 = getchar();
m = ((c1 - '0') * 10 + c2 - '0') * 60;
c = getchar(); //:
c1 = getchar(); c2 = getchar();
s = (c1 - '0') * 10 + c2 - '0';
po[i].arriveTime = h + m + s;
scanf("%d", &po[i].playTime);
if (po[i].playTime > 120) po[i].playTime = 120; //测试点4
po[i].playTime *= 60;
scanf("%d", &po[i].VIP);
c = getchar(); // \n
po[i].serveTime = -1;
}
scanf("%d%d", &k, &m);
for (int i = 1; i <= k; ++i) table[i] = -1;
for (int i = 1; i <= m; ++i) {
scanf("%d",&table[i]);
}
sort(po + 1, po + 1 + n, cmp);
for (int i = 1; i <= k; i++) busy[i] = 0,cnt[i]=0;
//测试点3,到达时间刚好为21点的player没有入场机会
for (int T = 8 * 3600; T < 21 * 3600; ++T)
if (nowServe > n) break;
else doit(T);
sort(po + 1, po + 1 + n, cmp2);
print();
return 0;
}