考查点:模拟题
提交情况:这道题题意要理清楚,尤其是其中的隐含信息,第一次用优先队列结果没有考虑空闲VIP桌要优先的情况,第二次出现段错误和各种错误,段错误是遍历下一个vip队员时候直接把当前位置+1还有在循环中没有判断位置指针小于总人数,所以访问下标越界,还有关系符写反了,搞了半天,还有两个小时的细节忘记处理了,这道题独题时候要理解好题意。
思路:用向量保存队员,table数组记录服务人数,其他基本暴力搜索即可通过,主要还是理清楚各种关系,分类好各种情况
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 10010
#define oo 0x3f3f3f3f
using namespace std;
struct Person{
int start,play,vip,wait;
}pn;
int table[11100];
int viptab[11100];
struct tab{
int id,endtime;
}tm,qtable[11100];
bool cmp(Person a,Person b){
return a.start<b.start;
}
bool cmpr(Person a,Person b)
{
return (a.start+a.wait)<(b.start+b.wait);
}
int main()
{
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif // LOCAL
int N;
int hh,mm,ss,play,vip;
scanf("%d",&N);
vector<Person> person;
FOR(i,1,N)
{
scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&pn.play,&pn.vip);
if(hh>=21)continue;
if(pn.play>=120){
pn.play=120*60;
}else{
pn.play=pn.play*60;
}
pn.start=hh*3600+mm*60+ss;
person.push_back(pn);
}
int m,k;
scanf("%d%d",&m,&k);
FOR(i,1,k)
{
int id;
scanf("%d",&id);
viptab[id]=1;
}
N=person.size();
sort(person.begin(),person.end(),cmp);
FOR(i,1,m)
{
tm.id=i;tm.endtime=8*3600;
qtable[i]=tm;
}
int num=N;
FOR(i,0,N-1)
{
if(person[i].vip==0){
tm.endtime=oo;
FOR(f,1,m)
{
if(qtable[f].endtime<tm.endtime){
tm=qtable[f];
}
}
if(tm.endtime<=person[i].start){
table[tm.id]++;
person[i].wait=0;
qtable[tm.id].endtime=person[i].start+person[i].play;
}else{
if(tm.endtime<21*3600){
table[tm.id]++;
}
if(viptab[tm.id]==0){
person[i].wait=tm.endtime-person[i].start;
qtable[tm.id].endtime+=person[i].play;
}else{
int cnt=i;
while(person[cnt].start<tm.endtime&&cnt<N){
if(person[cnt].vip==1){
break;
}
cnt++;
}
if(cnt==N||person[cnt].start>tm.endtime){
person[i].wait=tm.endtime-person[i].start;
tm.endtime+=person[i].play;
qtable[tm.id]=tm;
}else{
pn.start=person[cnt].start;
pn.wait=tm.endtime-person[cnt].start;
tm.endtime+=person[cnt].play;
qtable[tm.id]=tm;
person.erase(person.begin()+cnt);
person.push_back(pn);
i--;N--;
}
}
}
}else{
tm.endtime=oo;
FOR(f,1,m)
{
if(person[i].start>=qtable[f].endtime&&viptab[f]){
tm=qtable[f];break;
}
}
if(tm.endtime!=oo){
tm.endtime=person[i].start+person[i].play;
table[tm.id]++;
person[i].wait=0;
qtable[tm.id]=tm;
}else{
tm.endtime=oo;
FOR(f,1,m)
{
if(qtable[f].endtime<tm.endtime){
tm=qtable[f];
}
}
if(tm.endtime<=person[i].start){
table[tm.id]++;
person[i].wait=0;
qtable[tm.id].endtime=person[i].start+person[i].play;
}else{
if(tm.endtime<21*3600){
table[tm.id]++;
}
person[i].wait=tm.endtime-person[i].start;
qtable[tm.id].endtime+=person[i].play;
}
}
}
}
sort(person.begin(),person.end(),cmpr);
for(int i=0;i<num;i++)
{
if(person[i].start+person[i].wait<21*3600)
{
int servetime=person[i].start+person[i].wait;
if(person[i].wait%60>=30){
person[i].wait=person[i].wait/60+1;
}else{
person[i].wait/=60;
}
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",person[i].start/3600,person[i].start%3600/60,person[i].start%60,servetime/3600,servetime%3600/60,servetime%60,person[i].wait);
}else{
break;
}
}
FOR(i,1,m)
{
printf("%d",table[i]);
if(i<m)printf(" ");
}
return 0;
}