https://www.patest.cn/contests/pat-a-practise/1026
根据http://blog.csdn.net/jtjy568805874/article/details/50809719 修改
#include <cstdio>
#include <algorithm>
using namespace std;
#define inthree(i,j,k) scanf("%d%d%d", &i,&j,&k)
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=k;i>=j;i--)
const int maxn = 1e4 + 10;
int n, t[maxn], x, y, z, m, u, f[maxn], vis[maxn], cnt[maxn];//t[] 每张桌子的可用时间 , f[] 每张桌子是不是vip, vis[] 每个顾客是否被服务, cnt[] 每张桌子服务了多少客人
struct cust {
int x, y, f;
bool friend operator < (struct cust a, struct cust b) {
return a.x < b.x;
}
}a[maxn];
void putout(int x)
{
printf("%02d:%02d:%02d ", x / 3600, x / 60 % 60, x % 60);
}
void putmin(int x)
{
printf("%d\n", x / 60 + (x % 60 < 30 ? 0 : 1));
}
int main()
{
scanf("%d", &n);
rep(i, 0, n - 1)
{
scanf("%d:%d:%d", &x, &y, &z);
a[i].x = x * 3600 + y * 60 + z;
scanf("%d%d", &y, &a[i].f);
a[i].y = min(y * 60, 7200);
}
sort(a, a + n);
scanf("%d%d", &m, &u);
while (u--){ scanf("%d", &x); f[x-1] = 1;}
rep(i, 0, m - 1) t[i] = 8 * 3600;
rep(i, 0, n - 1)
{
if (vis[i]) continue;
int now = 0;//最早可用的桌子
rep(j, 0, m - 1) if (t[now] > t[j]) now = j;
if (max(t[now], a[i].x) >= 21 * 3600) break;//超出营业时间
if (t[now] <= a[i].x) //不用排队
{
int vip = -1;//如果当前用户是vip,则用vip桌中最小的
per(j, 0, m - 1)
{
if (t[j] <= a[i].x) now = j;
if (t[j] <= a[i].x&&f[j]) vip = j;
}
if (a[i].f && vip != -1) now = vip;
cnt[now]++;
putout(a[i].x); putout(a[i].x);
printf("0\n"); t[now] = a[i].x + a[i].y;
}
else //要排队
{
int vip = -1; //如果vip桌子同时可用
per(j, 0, m - 1) if (t[j] == t[now] && f[j]) vip = j;
if (vip != -1) //先处理vip桌子
{
int flag = 0; // 队列里是否有vip
for (int j = i; j < n&&a[j].x <= t[vip]; j++)
{
if (a[j].f&&!vis[j])
{
vis[j] = 1;
putout(a[j].x); putout(t[vip]);
putmin(t[vip] - a[j].x);
t[vip] += a[j].y;
flag = 1; break;
}
}
if (flag) { cnt[vip]++; i--; continue; }
}
cnt[now]++;//如果没有vip桌子同时可用,now是普通桌子, 给第一个人用
putout(a[i].x); putout(t[now]);
putmin(t[now]-a[i].x);
t[now] += a[i].y;
}
}
rep(i, 0, m - 1) printf("%d%s", cnt[i], i == m - 1 ? "\n" : " ");
return 0;
}