1014 Waiting in Line (30 分)思路和易错点分析

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:

  • The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
  • Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
  • Customer​i​​ will take T​i​​ minutes to have his/her transaction processed.
  • The first N customers are assumed to be served at 8:00am.

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, customer​1​​ is served at window​1​​ while customer​2​​ is served at window​2​​. Customer​3​​ will wait in front of window​1​​ and customer​4​​ will wait in front of window​2​​. Customer​5​​ will wait behind the yellow line.

At 08:01, customer​1​​ is done and customer​5​​ enters the line in front of window​1​​ since that line seems shorter now. Customer​2​​ will leave at 08:02, customer​4​​ at 08:06, customer​3​​ at 08:07, and finally customer​5​​ at 08:10.

Input Specification:

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.

Output Specification:

For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MMwhere 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.

Sample Input:

2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7

Sample Output:

08:07
08:06
08:10
17:00
Sorry

容易错的点有两个大家没AC可以先看看是否犯了这两个错误,1是:是否输出sorry是看顾客进行服务的时间不超过17点就行,不看完成时间。2是在一个顾客服务完毕后,还需要看是否有同时服务完毕的顾客,并且添加相应数量新的顾客入队

整体思路:答题上肯定是队列没得跑,但是队列数组怎么办? 这个我们可以利用结构体实现,结构体中有队列,我们可以生成结构体数组,也就有了多个队列了

struct node {//窗口
    int stime;
    int etime;
    queue id;
    queue queNum;
};

那么下一个就是思考如何保存顾客的服务的开始和结束时间,题目让输入几点几分,我们在表示时候肯定不能这样,换算太麻烦了,简单点就是记录顾客开始和结束服务时间距离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

你可能感兴趣的:(1014 Waiting in Line (30 分)思路和易错点分析)