传送门:UVA-822
有点绕。。。
多个客服同时选中某个请求这里,可以先将客服按等待时间和id排序,然后就可以顺序处理了。
AC代码:
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
int n;
//leave表示各种请求剩余的数量
int leave[30],m,tid[30],num[30],t0[30],t[30],dt[30],pid[10],k[10],ptid[10][30];
map<int,int> pq;//问题种类和存储位置的映射
int tm,now[10],period[10];//now表示当前在处理的种类,period表示客服已经处理了多长时间
int nowleft[30];//当前还有哪些未处理
bool cmp(int a,int b){
if(period[a]!=period[b]) return period[a]>period[b];
else return pid[a]<pid[b];
}
int main()
{
int cnt=1;
while(cin>>n){
if(!n) break;
pq.clear();
for(int i=0;i<n;++i) cin>>tid[i]>>num[i]>>t0[i]>>t[i]>>dt[i],leave[i]=num[i],pq[tid[i]]=i;
cin>>m;
for(int i=0;i<m;++i){
cin>>pid[i]>>k[i];
for(int j=0;j<k[i];++j) cin>>ptid[i][j];
}
memset(nowleft,0,sizeof(nowleft));
memset(period,0,sizeof(period));
for(int i=0;i<m;i++) now[i]=-1;
tm=0;//表示时间
while(1){
int flag=1;
for(int i=0;i<n;++i) if(leave[i]||nowleft[i]) {flag=0;break;}
for(int i=0;i<m;++i){
if(now[i]==-1) continue;
int tmp=pq[now[i]];//当前处理的问题索引
if(period[i]<t[tmp]){flag=0;break;}
}
if(flag) break;
for(int i=0;i<n;++i) if(tm>=t0[i]&&(tm-t0[i])%dt[i]==0&&leave[i]) ++nowleft[i],--leave[i];
int tmp[10];
for(int i=0;i<m;++i) tmp[i]=i;
sort(tmp,tmp+m,cmp);//按要求先对客服排序
for(int i=0;i<m;++i){
int yu=tmp[i];
if(now[yu]!=-1&&period[yu]<t[pq[now[yu]]]){++period[yu];continue;}//当前正在处理问题
for(int j=0;j<k[yu];++j){//可以处理新问题
int pos=pq[ptid[yu][j]];
if(nowleft[pos]>0){
--nowleft[pos];
now[yu]=tid[pos];
period[yu]=1;
break;
}
}
}
++tm;
}
printf("Scenario %d: All requests are serviced within %d minutes.\n",cnt++,tm);
}
return 0;
}