分析:思路想的不对,写了很久都处理不了k>n?mk>n*mk>n?m的情况,下面这种写法实现了当k<n?mk<n*mk<n?m的情况。
这题比较关键和有技巧的一点就是选择时间作为循环变量(当然这只是其中一种方法),也更好理解。每次时间增加后,先查看队头的人是否有服务完成的,如果是则出队,并计算其后顾客(如果有)的结束时间:当前时间+顾客服务时间;再查看是否有人可以排进窗口队伍中。
借鉴别人代码写的,很好的一道模拟题目。
#include<bits/stdc++.h>
#define maxn 1010
using namespace std;
int serveTime[maxn];//记录开始时间
int endTime[maxn]; //记录结束时间
queue<int> que[110];
int n,m,k,q;
int main(){
//std::ios::sync_with_stdio(false);cin>>n>>m>>k>>q;for(int i=1;i<=k;i++){
cin>>serveTime[i];}for(int i=0;i<n;i++){
if(!que[i].empty()) {
que[i].pop();}}int sum=0;int cnt=1;//遍历时间for(int ti=0;ti<540;ti++){
for(int i=0;i<n;i++){
for(int j=0;j<que[i].size();j++){
if(ti==endTime[que[i].front()]){
que[i].pop();sum--;//更新下一个人的结束时间if(!que[i].empty()){
int tmp=que[i].front();endTime[tmp]=ti+serveTime[tmp];}}}}while(sum<m*n&&cnt<=k){
int minn=0;for(int i=0;i<n;i++){
if(que[minn].size()>que[i].size()){
minn=i; //找到当前人数最少的队伍}if(que[minn].size()==0) endTime[cnt]=ti+serveTime[cnt]; //如果没人,则直接开始记时间if(que[minn].size()<m&&cnt<=k){
que[minn].push(cnt);cnt++;sum++;}}}}for(int i=0;i<q;i++){
int x;cin>>x;if(endTime[x]==0) cout<<"Sorry"<<endl;else {
int hour=endTime[x]/60+8;int minute=endTime[x]%60;printf("%02d:%02d\n",hour,minute);}}return 0;
}
wa.
#include<bits/stdc++.h>
using namespace std;
typedef struct Node{
int id,dealTime;int sta,edd;
}node;
node pe[1100];
int n,m,k,q;
void solve(){
bool flag=false;int pos=0;for(int i=0;i<n;i++){
pe[i].edd=pe[i].dealTime;for(int j=1;j<=m;j++){
pe[i+j*n].sta=pe[i+(j-1)*n].edd;pe[i+j*n].edd=pe[i+j*n].sta+pe[i+j*n].dealTime;pos++;if(pos>k){
flag=true;break;}}if(flag) break;}
}
void print(int t){
int hour=t/60;int minute=t%60;hour+=8;if(hour<10){
cout<<"0"<<hour<<":";}else cout<<hour<<":";if(minute<10) {
cout<<"0"<<minute<<endl;}else cout<<minute<<endl;
}
int main(){
std::ios::sync_with_stdio(false);cin>>n>>m>>k>>q;for(int i=1;i<=k;i++){
cin>>pe[i].dealTime;pe[i].id=i;}if(k<=n*m){
solve();}else{
solve(); //前k*m个人先处理一下}for(int i=0;i<q;i++){
int x;cin>>x;if(pe[x].edd>=540) cout<<"Sorry"<<endl;else print(pe[x].edd);}return 0;
}