比较好的思路如下:
#include<iostream> #include<cstdio> #include<queue> using namespace std; const int K=1004,N=22; int cost[K],done[K],sum[N],n,m,k,q; queue<int>que[N]; void conduct(){ int i=0; for(;i<n*m &&i<k;++i){ sum[i%n]+=cost[i]; done[i]=sum[i%n]; que[i%n].push(i); } for(;i<k;++i){ int th; for(int mmin=1<<30,j=0;j<n;++j) if(done[que[j].front()]<mmin) mmin=done[que[th=j].front()]; sum[th]+=cost[i]; done[i]=sum[th]; que[th].pop(); que[th].push(i); } } int main(){ cin>>n>>m>>k>>q; for(int i=0;i<k;++i) cin>>cost[i]; conduct(); while(q--){ int no;cin>>no;--no; if(done[no]-cost[no]>=540) printf("Sorry\n"); else printf("%02d:%02d\n",8+done[no]/60,done[no]%60); } }在这种方式中,最早出队的那个队列并非累计服务时间最少的那个队列。
比较坏的思路如下
#include<vector> #include<climits> #include<iostream> #include<list> using namespace std; const int N=1003; int use[N],leave[N],serve[N],n,m,k,q,outline,lastleavetime; struct node{int left,id;node(int a,int b):id(a),left(b){}}; typedef list<node> window; int main(){ cin>>n>>m>>k>>q; for(int i=0;i<k;++i)cin>>use[i]; vector<window>que(n); while(outline<k && outline<n*m){ que[outline%n].emplace_back(outline,use[outline]); outline++;} // find a man next to leave,and make him leave,refresh the lefttime in que,and make // the one outline to wait in line,if any. while(true){ int mmin=INT_MAX,nth=-1; for(int i=0;i<n;++i) if(que[i].size() &&que[i].front().left<mmin) mmin=que[nth=i].front().left; if(nth==-1)break; auto x=que[nth].front(); que[nth].pop_front(); leave[x.id]=lastleavetime+x.left; lastleavetime=leave[x.id]; if(que[nth].size()) serve[que[nth].front().id]=lastleavetime; mmin=INT_MAX;int nth2=-1; for(int i=0;i<n;++i) if(que[i].size()){ if(i!=nth) que[i].front().left-=x.left; if(que[i].size()<mmin) mmin=que[nth2=i].size(); }//if(que[.. if(outline<k) {que[nth2].emplace_back(outline,use[outline]);outline++;} }//while(true) while(q--){ int nth;cin>>nth;--nth; if(serve[nth]>=540)printf("Sorry\n"); else printf("%02d:%02d\n",8+leave[nth]/60,leave[nth]%60); }//while(q--.. }