题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805472333250560
这个题,难的飞起。自己写出来只有一半对。里面逻辑特别复杂。
二刷这个题,有两点问题:
1.题目是假保证,要排除21点之后来的人。
2.没有单独开vector,而是直接在原数组上操作,然后用num记录人数,最后排序的时候可能忽略一种情况,即并不是排前num个人,因为有可能之后有vip已经抢先占桌了,所以break出去的时候num是小于真实的num的。所以刚开始进行初始化,然后排序把所有人一起排。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 1e9;
int n, k, m;
int st = 8 * 3600, ed = 21 * 3600, ivip = -1;
struct players{
int t, st, p;
bool v;
}temp;
struct tables{
int t, num;
bool v;
}table[110];
vector<players> player;
bool cmp1(players a, players b){
return a.t < b.t;
}
bool cmp2(players a, players b){
return a.st < b.st;
}
void nextvip(){
ivip++;
while(ivip <= player.size() && !player[ivip].v){
ivip++;
}
}
void give(int a, int b){
if(player[a].t >= table[b].t){
player[a].st = player[a].t;
}
else
player[a].st = table[b].t;
table[b].t = player[a].st + player[a].p;
table[b].num++;
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
int hh, mm, ss, pp, vip;
scanf("%d:%d:%d %d %d", &hh, &mm, &ss, &pp, &vip);
temp.t = hh * 3600 + mm * 60 + ss;
temp.st = ed;
if(temp.t >= ed) //题目假保证
continue;
if(pp > 120)
pp = 120;
temp.p = pp * 60;
temp.v = vip;
player.push_back(temp);
}
sort(player.begin(), player.end(), cmp1);
scanf("%d%d", &k, &m);
for(int i = 1; i <= k; i++){
table[i].t = st;
table[i].num = 0;
table[i].v = 0;
}
for(int i = 0; i < m; i++){
int vip;
scanf("%d", &vip);
table[vip].v = 1;
}
nextvip();
int i = 0;
while(i < player.size()){
int u = -1, MIN = INF;
for(int j = 1; j <= k; j++){
if(table[j].t < MIN){
MIN = table[j].t;
u = j;
}
}
if(table[u].t >= ed)
break;
if(player[i].v && i < ivip){
i++;
continue;
}
if(table[u].v){
if(player[i].v){
give(i, u);
if(i == ivip)
nextvip();
i++;
}else{
if(ivip < player.size() && player[ivip].t <= table[u].t){
give(ivip, u);
nextvip();
}else{
give(i, u);
i++;
}
}
}else{
if(player[i].v){
int v = -1, MIN = INF;
for(int j = 1; j <= k; j++){
if(table[j].v && table[j].t < MIN){
MIN = table[j].t;
v = j;
}
}
if(v != -1 && player[i].t >= table[v].t)
give(i, v);
else
give(i, u);
if(i == ivip)
nextvip();
i++;
}else{
give(i, u);
i++;
}
}
}
sort(player.begin(), player.end(), cmp2);
for(int i = 0; i < player.size() && player[i].st < ed; i++){
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", player[i].t/3600, player[i].t%3600/60, player[i].t%60, player[i].st/3600, player[i].st%3600/60, player[i].st%60, (player[i].st - player[i].t + 30)/60);
}
for(int i = 1; i <= k; i++){
printf("%d", table[i].num);
if(i < k)
printf(" ");
}
return 0;
}