PAT (Advanced Level) Practice1017 Queueing at Bank(25 分)

题目链接

Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and there is a window available. It is assumed that no window can be occupied by a single customer for more than 1 hour.
Now given the arriving time T and the processing time P of each customer, you are supposed to tell the average waiting time of all the customers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=10000) - the total number of customers, and K (<=100) - the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS - the arriving time, and P - the processing time in minutes of a customer. Here HH is in the range [00, 23], MM and SS are both in [00, 59]. It is assumed that no two customers arrives at the same time.
Notice that the bank opens from 08:00 to 17:00. Anyone arrives early will have to wait in line till 08:00, and anyone comes too late (at or after 17:00:01) will not be served nor counted into the average.

Output Specification:

For each test case, print in one line the average waiting time of all the customers, in minutes and accurate up to 1 decimal place.

Sample Input:

7 3
07:55:00 16
17:00:01 2
07:59:59 15
08:01:00 60
08:00:00 30
08:00:02 2
08:03:00 10

Sample Output:

8.2

题意

银行有k个窗口,每个窗口前排一个人,剩下的在黄线外排队等候服务。输入N个人,K个窗口,下面N行,每行给出到达时刻HH:MM:SS,以及服务时间(分钟),对每个人的服务不超过一小时,从8:00:00开始,17:00:00之后到达的就不服务了。求被服务的人的平均服务时长(分钟)。

思路

把时间都化成秒,从八点开始为第0秒,下午五点就是32400秒,记录每个人的到达时间(超过17点的去掉)、服务时长(超过60的,记作60)。然后模拟这一过程,每次找出窗口结束时间最小的服务下一个顾客。注意如果窗口结束了上个人的服务,而下一个人还没到来,窗口的结束时间要加上这段等待下个人的时间。

#include
#include
#include
#include
#include

using namespace std;

const int N=10005;
const int K=105;

struct node{
    int arrive_time;
    int serve_time;
}cus[N];
int win_fin_time[K];  //窗口结束服务时间

bool cmp(node x, node y)
{
    return x.arrive_timeint main()
{
    int n,k,HH,MM,SS,x,amount,cnt=0;
    memset(cus,0,sizeof cus);
    memset(win_fin_time,0,sizeof win_fin_time);
    scanf("%d%d",&n,&k);
    while(n--){
        scanf("%d:%d:%d",&HH,&MM,&SS);
        scanf("%d",&x);
        if(x>60) x=60;  //服务时长不超过60
        amount=(HH-8)*60*60+MM*60+SS;  //换算成秒
        if(amount>32400) continue;  //超过17:00的直接舍弃
        cus[cnt].arrive_time=amount;
        cus[cnt].serve_time=x*60;
        cnt++;
    }
    sort(cus,cus+cnt,cmp);
    int pos, wait_time=0; x=0;
    for(int i=0;i//先对每个窗口分配一个人,如果已经有人的话
        if(cus[i].arrive_time<=0 && x//有人且有窗口
            win_fin_time[x++]=cus[i].serve_time;
            wait_time = wait_time - cus[i].arrive_time;
            pos=i+1;
        }
        else{
            pos=i; break;
        }
    }

    if(pos==cnt){
        printf("%.1lf\n",wait_time/(60.0*cnt));
        return 0;
    }

    int t,minn;
    for(int i=pos;i//遍历剩下的每一个人
        t=cus[i].arrive_time;
        x=0,minn=win_fin_time[0];
        for(int j=1;j//每次选出结束时间最小的窗口对下一个进行服务
            if(win_fin_time[j]if(t>=minn){ //如果顾客来的时刻在窗口结束上一个服务之后!
            //窗口结束时间=顾客来的时刻+对他的服务时长。特别注意!!!别忘了
            win_fin_time[x]=t+cus[i].serve_time;
        }
        else{  //否则,等待时间+=顾客等待窗口结束的时间,该窗口结束时间
            wait_time += (win_fin_time[x]-t);
            win_fin_time[x]+=cus[i].serve_time;
        }
     //   cout<<"...."<
    }
    printf("%.1lf\n",wait_time/(60.0*cnt));
    return 0;
}

你可能感兴趣的:(PAT,ACM_构造)