这题就是疯狂的分情况讨论,因为k最大100所以随便折腾,即使把堆中的所有元素都pop出来也没关系。这题的难点就在于要把各种细节想到。
#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int N=1e4+10;
int n,k,u;
struct node
{
int come,cost,type;
bool operator<(const node&a)const
{
return come<a.come;
}
}cust[N];
bool vip[110];
vector<PII> ans;
int cnt=0,ans2[110];
void tran(int x)
{
int h=x/3600;
x%=3600;
int m=x/60;
x%=60;
printf("%02d:%02d:%02d ",h,m,x);
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int h,m,s,t,type;
scanf("%d:%d:%d %d %d",&h,&m,&s,&t,&type);
type^=1;
int sum=h*3600+m*60+s;
if(sum>=21*3600) continue;
cust[cnt++]={sum,min(2*3600,t*60),type};
}
priority_queue<PII,vector<PII>,greater<PII>> heap;
cin>>k>>u;
for(int i=0;i<u;i++)
{
int x;
cin>>x;
vip[x]=true;
}
for(int i=1;i<=k;i++) heap.push({8*3600,i});
sort(cust,cust+cnt);
int q[N],hh=0,tt=-1;
int qv[N],hhh=0,ttt=-1;
for(int i=0;i<cnt||hh<=tt||hhh<=ttt;)
{
int serverT=heap.top().first,j=heap.top().second;
if(serverT>=21*3600) break;
vector<int> tmp;
while(i<cnt&&cust[i].come<=serverT)
{
if(!cust[i].type) qv[++ttt]=i,i++;
else q[++tt]=i,i++;
}
if(hh<=tt||hhh<=ttt)
{
int t=-1;
if(hhh<=ttt)
{
if(vip[j])
{
t=qv[hhh++];
heap.pop();
}else
{
bool flag=false;
vector<PII> tmp;
while(heap.size()&&heap.top().first==serverT)
{
auto temp=heap.top();heap.pop();
tmp.push_back(temp);
if(vip[temp.second])
{
flag=true;
break;
}
}
if(!flag)
{
for(int i=1;i<tmp.size();i++) heap.push(tmp[i]);
if(hh<=tt&&cust[q[hh]].come<cust[qv[hhh]].come) t=q[hh++];
else t=qv[hhh++];
}else
{
j=tmp.back().second;
for(int i=0;i<tmp.size()-1;i++) heap.push(tmp[i]);
t=qv[hhh++];
}
}
}else
{
t=q[hh++];
heap.pop();
}
ans2[j]++;
ans.push_back({serverT,cust[t].come});
heap.push({serverT+cust[t].cost,j});
}else
{
int come=cust[i].come,cost=cust[i].cost,type=cust[i].type;
int minu=110,minu2=110;
vector<PII> tmp;
while(heap.size()&&heap.top().first<=come)
{
auto t=heap.top();heap.pop();
tmp.push_back(t);
if(vip[t.second]) minu=min(minu,t.second);
minu2=min(minu2,t.second);
}
if(!type&&minu<=100) ;
else minu=minu2;
for(int i=0;i<tmp.size();i++)
{
if(tmp[i].second==minu)
{
heap.push({cost+come,minu});
ans2[minu]++;
}else heap.push(tmp[i]);
}
ans.push_back({come,come});
i++;
}
}
sort(ans.begin(),ans.end());
for(auto p:ans)
{
tran(p.second),tran(p.first);
double t=(p.first-p.second)/60.0;
printf("%d\n",int(round(t)));
}
cout<<ans2[1];
for(int i=2;i<=k;i++) cout<<' '<<ans2[i];
return 0;
}