1. 起止时间8.00-21.00之间
2.vip优先用vip空闲桌最小编号 ,不是所有空闲桌子
3. 使用时间不超过120*60秒
4.四舍五入 即round 不是向上取整ceil
//代码只有26,刚开始只有21 ,改为四舍五入以后22 后来认为是在空闲桌子存在时那那一刻 也存在排队的, 即排队的时候 有几个的结束时间恰好相等,后来推翻了这个观点 看了别人的坑点 发现vip优先使用vip空闲桌子,不是编号最小的桌子,改了也只有26
1和2的测试点过不去
在空闲的桌子使用那注释了两端代码 都是修改时留下的 第一段仅考虑了空闲时刻没有排队的
第二段则是考虑了排队的 但依然没有改善
while段则是vip与vip桌子的对应
/*
思路:把所有的排一队 有优先级的在单独排一队
桌子:(优先队列) 所有可用桌子排一队 有优先级的排一队
优先级排一队主要是为了vip使用时的操作
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int ST = 8*60*60;
const int ET = 21*60*60;
int pre = ST;
struct P {
int gettime;
int pt;
int p;
P() {
gettime = ET;
pt = 0;
}
friend bool operator <(const P& a, const P& b) {
return a.gettime > b.gettime;
}
};
struct Table {
int gt, st, cnt, et;//到达 服务 第几个桌子 结束时长
int vip;
Table() {
gt = ST;
st = ST;
et = ST;
cnt = 0;
vip = 0;
}
friend bool operator <(const Table& a, const Table& b) {
if(a.et == b.et){
return a.vip < b.vip;
}
return a.et > b.et;
}
};
struct IDX {
int i;
int et;
IDX() {
et = ST;
}
friend bool operator <(const IDX& a, const IDX& b) {
if(a.et == b.et)
return a.i > b.i;
return a.et > b.et;
}
};
priority_queue<P> q, p;
priority_queue<IDX > ans, ansp;
priority_queue<Table> a;
int main() {
int n, k, m;
cin >> n;
for(int i=0; i<n; i++) {
int h, m, s, pt;
P tmp;
scanf("%d:%d:%d %d %d", &h, &m, &s, &pt, &tmp.p);
tmp.gettime = h*3600+m*60+s;
if(tmp.gettime>ET) continue;
if(pt > 120) {
tmp.pt = 120*60;
} else tmp.pt = pt*60;
if(tmp.p == 1) {
p.push(tmp);
}
q.push(tmp);
}
scanf("%d%d", &k, &m);
int flag[k];
int Sum[k];
for(int i=0; i<k; i++) {
Table tmp;
tmp.cnt = i;
//a.push(tmp);
IDX t1;
t1.i = i;
ans.push(t1);
}
memset(flag, 0, sizeof(flag));
memset(Sum, 0, sizeof(Sum));
for(int i=0; i<m; i++) {
IDX t1;
cin >> t1.i;
t1.i -=1;
ansp.push(t1);
flag[t1.i] = 1;
}
int j = 0;
int all = 0;
while(!q.empty()) {
P tmp = q.top(), tmpq;
Table tt;
if(!p.empty()) {//>=
tmpq = p.top();
if(tmp.p && tmp.gettime < tmpq.gettime) {//默认不会有相同时间到达的
q.pop();//都是vip 不同则说明 有vip tmp用了特区
continue;//从头开始
} else if(tmp.gettime > tmpq.gettime) {
p.pop();
continue;
}
}else{
if(tmp.p == 1){
q.pop();
continue;
}
}
// cout << endl << a.size() << endl << endl << endl;
while(!a.empty()) {
IDX t1;
tt = a.top();
while(tt.et <= tmp.gettime) {//可以在下一个之前释放的,就让他释放
t1.et = tt.et;
t1.i = tt.cnt;
if(flag[tt.cnt]) {
ansp.push(t1);
}
ans.push(t1);
a.pop();
if(a.empty()) break;
tt = a.top();
}
break;
}
IDX idx;
/* if(!ans.empty()) {//有空闲桌子
idx = ans.top();
if(flag[idx]) {
ansp.pop();
}
ans.pop();
tt.gt = tt.st = tmp.gettime;
if(tt.st < ST) {
tt.st = ST;
}
tt.et = tt.st+tmp.pt;
tt.cnt = idx;
q.pop();
if(tt.st >= ET && tt.et > ET) {
break;
}else if(tt.et > ET){
tt.et = ET;
}
Sum[tt.cnt]++;
// printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
}*/
bool flagt = false;
while(!ans.empty()) {//有空闲桌子
idx = ans.top();
if(flag[idx.i]) {//都是优先级 排整齐
if(!ansp.empty()) {
IDX t2 = ansp.top();
if(t2.i == idx.i) {
;
} else if(t2.i > idx.i) {
ans.pop();
continue;
} else if(t2.i < idx.i) {
ansp.pop();
continue;
}
}
else {//在ansp找不到 说明之前ansp pop过
ans.pop();
continue;
}
}
tt.gt = tt.st = tmp.gettime;
tt.cnt = idx.i;
if(!ansp.empty() && tmp.gettime == tmpq.gettime) {//是vip 并有vip桌子
tt.cnt = ansp.top().i;
tt.vip = 1;
ansp.pop();
} else ans.pop();
if(tt.st < ST) {
tt.st = ST;
}
tt.et = tt.st+tmp.pt;
q.pop();
if(tt.st >= ET) {
break;
} else if(tt.et > ET) {
tt.et = ET;
}
flagt = true;
Sum[tt.cnt]++;
// cout << tt.cnt<< "============";
// printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
break;
}
/*
if(!ans.empty()) {//有空闲桌子 可能之前堵得
IDX idx = ans.top();
if(flag[idx.i] && idx.et >= tmpq.gettime) { //VIP桌 且之前有等待的vip
//VIP上
ansp.pop();
p.pop();
tt.gt = tmpq.gettime;
tt.st = idx.et;
tt.et = tt.st+tmpq.pt;
} else if(idx.et >= tmp.gettime) {//之前有等待的普通||vip
q.pop();
tt.gt = tmp.gettime;
tt.st = idx.et;
tt.et = tt.st+tmp.pt;
} else {//空闲一会才来的玩家
q.pop();
tt.gt = tt.st = tmp.gettime;
tt.et = tt.st+tmp.pt;
}
if(tt.st >= ET && tt.et>ET) {//ET之前未开始
break;
} else if(tt.et > ET) {
tt.et = ET;
}
ans.pop();
if(tt.st < ST) {
tt.st = ST;
}
tt.cnt = idx.i;
if(tt.st >= ET && tt.et > ET) {
break;
} else if(tt.et > ET) {
tt.et = ET;
}
Sum[tt.cnt]++;
// printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
} */
if(!flagt) { //需等待
a.pop();
if(flag[tt.cnt] && tt.et >= tmpq.gettime) { //等待一会的有优先级 并且有有vip到了
//VIP上
p.pop();
tt.gt = tmpq.gettime;
tt.st = tt.et;
tt.et = tt.st+tmpq.pt;
} else {
q.pop();
tt.gt = tmp.gettime;
tt.st = tt.et;
tt.et = tt.st+tmp.pt;
}
if(tt.st >= ET) {
break;
} else if(tt.et > ET) {
tt.et = ET;
}
Sum[tt.cnt]++;
// printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
}
a.push(tt);
all++;
}
for(int i=0; i<k-1; i++) {
printf("%d ", Sum[i]);
}
printf("%d\n", Sum[k-1]);
return 0;
}