Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:
Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.
For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.
At 08:01, customer1 is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.
Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (≤20, number of windows), M (≤10, the maximum capacity of each line inside the yellow line), K (≤1000, number of customers), and Q(≤1000, number of customer queries).
The next line contains K positive integers, which are the processing time of the K customers.
The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.
For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM
where HH
is in [08, 17] and MM
is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output Sorry
instead.
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
08:07
08:06
08:10
17:00
Sorry
容易错的点有两个大家没AC可以先看看是否犯了这两个错误,1是:是否输出sorry是看顾客进行服务的时间不超过17点就行,不看完成时间。2是在一个顾客服务完毕后,还需要看是否有同时服务完毕的顾客,并且添加相应数量新的顾客入队
整体思路:答题上肯定是队列没得跑,但是队列数组怎么办? 这个我们可以利用结构体实现,结构体中有队列,我们可以生成结构体数组,也就有了多个队列了
struct node {//窗口
int stime;
int etime;
queue
queue
};
那么下一个就是思考如何保存顾客的服务的开始和结束时间,题目让输入几点几分,我们在表示时候肯定不能这样,换算太麻烦了,简单点就是记录顾客开始和结束服务时间距离8点有多久(用分钟表示),最后 输出时候进行一次换算就好了。可以更直接点,在窗口结构体直接声明两个变量 int stime; int etime;,用来记录当前服务的客户 开始时间 和完成时间(距离8点的分钟数),当一个客户服务完毕,我们只需要完成下面两步就好了。
stime=etime;
etime=etime+新顾客所需服务分钟数
代码如下,注释的算详细了,可以参考一下
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node {//窗口
int stime;
int etime;
queue id;//记录当前窗口队列中客户的id,其实用不上,随手加上了
queue queNum;
};
int getshi(int n) {//返回分钟数对应的小时
int out=n/60;
int out2=out+8;
return out2;
}
int getfen(int n) {
int out=n%60;
return out;
}
int main() {
int N,M,K,Q;
cin>>N>>M>>K>>Q;
//N是窗口数 M每个窗口容纳个数 K顾客数 Q查询数目
int guke[K];//记录顾客对应处理时间
for(int i=0; i>guke[i];
}
int chaxun[Q];//记录需要查询的顾客编号
for(int i=0; i>chaxun[i];
}
int getchaxun[1001]= {0}; //根据数组位置快速查询顾客完成时间
int getrudui[1001]= {0}; //根据数组位置快速查询顾客入队的时间
vector que(N); //每个窗口一个结构体,结构体里有队列
int pos=0;//用来表示顾客的个数,
for(int m=0; m0)
if(que[i].etime0)//非空队列/窗口
if(que[i].etime==minn) {//如果窗口完成时间刚好是最短的,出队列,表示已经完成了
outNum++;//完成顾客的计数
//保存该用户出队时间(完成所需的时长)和开始服务的时间,
int gukeID=que[i].id.front();
getchaxun[gukeID]=que[i].etime;
getrudui[gukeID]=que[i].stime;
//记录开始服务的时间是因为在下午5点前能服务就不能输出sorry,不论什么时候完成
//出队列
que[i].queNum.pop();
que[i].id.pop();
//如果窗口还有顾客需要再次开始,窗口结构体记录下一个顾客的完成时间
if(que[i].queNum.size()>0) {
que[i].stime=que[i].etime;
que[i].etime=que[i].etime+que[i].queNum.front();
} else {//没有顾客都赋值为0,避免 麻烦
que[i].etime=0;
que[i].stime=0;
}
}
}
}
} else {
//一方面以OUTnum判断是否所有顾客结束时间都记录了
//另一方面每次循环都确定那个顾客完成业务了,
//并且判断是否需要添加新的顾客到队列中 使用pos判断
while(outNum!=K) {
int q=0;
while(que[q].queNum.size()==0) {
q++;
}
int zuixiao=q;
int minn=que[q].etime;
for(int i=q+1; i0) {
if(que[i].etime0)
if(que[i].etime==minn) {
outNum++;//计数
fishNum++;
//保存该用户出队时间
int gukeID=que[i].id.front();
getchaxun[gukeID]=que[i].etime;
getrudui[gukeID]=que[i].stime;
//出队列
que[i].queNum.pop();
que[i].id.pop();
//如果还有从新计时
if(que[i].queNum.size()>0) {
que[i].stime=que[i].etime;
que[i].etime=que[i].etime+que[i].queNum.front();
}
}
}
for(int this_turn=0; this_turnque[i].queNum.size()) {
shaonum=que[i].queNum.size();
shaopos=i;
}
}
//找到最短的队列,添加进去
que[shaopos].queNum.push(guke[pos++]);
que[shaopos].id.push(pos);
//如果窗口就你一个了,需要再次赋值窗口结构体的开始时间和完成时间变量
if(que[shaopos].queNum.size()==1) {
que[shaopos].stime=que[shaopos].etime;
que[shaopos].etime=que[shaopos].etime+que[shaopos].queNum.front();
}
}
}
}
}
for(int i=0; i