PAT甲级-1014 Waiting in Line (30分)

点击链接PAT甲级-AC全解汇总

题目:
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 customers 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:MM whereHH 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

题意:
银行有N个窗口,每个窗口前面队伍最多排M个人,一共有K个人,编号从1 ~ K,需要的时间在第二行输入,有Q个人查询他几点可以结束,Q个查询的编号在第三行输出。
排序的规则是:

  1. 排在人少的队伍,如果人数一样多,选择队的编号最小的。(意味着前N*M人的队伍是一开始就可以确定的。)
  2. 第N*M+1个人开始,排不进所有队伍,在后面等待,直到某队有人结束之后,该队空出来了一个位置再排进去。(也就是选择当前排头时间最少的那队)

我的思路:
因为所有人,都是在一开始一起进来的,所以不存在 一共有三条队伍 第三个人进来的时候第一个人已经结束(则排在第一条队伍),无论如何他都会在第三条队伍排着。
所以前N*M的人是固定排到对应的队伍的,之后的人会选择排头时长最少的队伍排进去。
每排一个人到这条队伍,直接计算这条队伍需要的累计总时长,这样也就知道这个人完成时候的时间。

注意: 只要17:00安排上的,都会处理,哪怕结束时间超过了17:00也会处理those customers who cannot be served before 17:00, you must output Sorry instead

我的代码:

#include
using namespace std;

int N,M,K,Q;
//所有队伍当前的情况
vector<queue<int> >all_queue;
void init(int n){
     
    queue<int>q;
    while(n-->0)all_queue.push_back(q);
}

//超过N*M人之后排在排头剩余时间最少的队伍
int min_front_index(){
     
    int min_time=INT_MAX,res_i=-1;
    for(int i=0;i<N;i++)//找排头时间最少的队伍
        min_time=min(min_time,all_queue.at(i).front());

    for(int i=0;i<N;i++)
    {
     
        if(all_queue.at(i).front()==min_time&&res_i==-1)
        {
     
            res_i=i;//编号最小的那个排头时间最小的队伍
            all_queue.at(i).pop();
        }
        else//其他每队排头减去这个最小排头的时间,不可能为负
        {
     
            all_queue.at(i).front()-=min_time;//为0的下次再pop
        }
    }
    return res_i;
}

int main()
{
     
    cin>>N>>M>>K>>Q;
    init(N);//初始化所有队伍
    int sum_time[N]={
     0};//所有窗口的累计时间
    int time_when_finished[K]={
     0};//每人结束时候的时间
    //输入时间
    for(int i=0;i<K;i++)
    {
     
        //队伍号,i
        int index=(i<N*M)?(i%N):min_front_index();

        int time;
        cin>>time;
        all_queue.at(index).push(time);//此人加入队列
        bool flag_yes=sum_time[index]<540?true:false;
        sum_time[index]+=time;//该队结束时间
        time_when_finished[i]=flag_yes?sum_time[index]:-1;//此人结束时间
    }

    //查询时间
    for(int i=0;i<Q;i++)
    {
     
        int q;
        cin>>q;
        q=time_when_finished[q-1];
        if(q==-1)cout<<"Sorry"<<endl;
        else printf("%02d:%02d\n",8+q/60,q%60);
    }
    return 0;
}

你可能感兴趣的:(PAT,算法)