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;
}