(Java)1017 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.

假设一家银行有K个窗口可供服务。窗户前有一条黄线,把等候区分成两部分。所有的顾客都必须在黄线后面排队等候,直到轮到他/她得到服务,并且有一个窗口。假设任何窗口都不能被单个客户占用超过1小时。
现在给定每个客户的到达时间T和处理时间P,您应该告诉所有客户的平均等待时间。

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤104) - 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.

每个输入文件包含一个测试用例。对于每种情况,第一行包含2个数字:N(≤104)-客户总数,K(≤100)-窗口数。接下来是N行,每行包含2次:HH:MM:SS-到达时间,P-客户的处理时间(以分钟为单位)。这里HH在[00,23]的范围内,MM和SS都在[00。59]。假设没有两个客户同时到达。
请注意,银行的营业时间为08:00至17:00。任何提前到达的人都必须排队等候至08:00,任何迟到的人(17:00:01或之后)都不会得到服务,也不会计入平均数。

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.

对于每个测试用例,在一行中打印所有客户的平均等待时间,以分钟为单位,精确到小数点后1位。

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

思路:本题和1014题很相似,但也有很多不同的地方!!

注意:1.如果顾客的到达时间是16:50分,处理时间是30分钟,这个顾客银行也是要加班处理的

           2.如果每个顾客的到达时间都在17:00之前,如果按照1014的思路,循环结束不了,所以我们要增加一个哨兵顾客,来结束循环,设置他的到达时间是999999(比17*3600大就行了)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Comparator;
class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(bf);
        in.nextToken();
        int n = (int)in.nval;
        in.nextToken();
        int k = (int)in.nval;
        //这里需要手动创建一个额外的顾客,把他的到达时间设置为比17*3600大的一个数,来结束循环!!,很重要这里
        customer []c = new customer[n+1];
        //先创建好对象
        c[n] = new customer();
        for(int i = 0 ; i < n;i++)
        {
            String []s = bf.readLine().split(" ");
            String []time = s[0].split(":");
            c[i] = new customer();
            //将时间化为秒进行操作,方便一点
            c[i].come_time = Integer.parseInt(time[0]) * 3600 + Integer.parseInt(time[1]) * 60 + Integer.parseInt(time[2]);
            c[i].process_time = Integer.parseInt(s[1]) * 60;
            //每个顾客最多只能占用一个小时的窗口
            if(c[i].process_time > 3600) c[i].process_time = 3600;
        }
        //设置一个哨兵顾客,结束循环
        c[n].come_time = 9999999;
        //将顾客的达到时间从小到大进行排序,先到的先处理
        Arrays.sort(c, new Comparator<customer>() {
            @Override
            public int compare(customer o1, customer o2) {
                return o1.come_time - o2.come_time;
            }
        });
        
        int next = 0;
        //k个窗口
        int []window = new int[k];
        //初始化窗口,-1代表空闲
        for(int i = 0 ; i < k ;i++)
        {
            window[i] = -1;
        }
        //记录等待时间
        double sum = 0;
        for(int time = 3600 * 8 ;c[next].come_time <= 3600 * 17 ; time ++)
        {
            //送客
            for(int i = 0 ; i < k ;i ++)
            {
                //如果窗口有人
                if(window[i] >= 0)
                {
                    int j = window[i];
                    if(c[j].leave_time == time)
                    {
                        window[i] = -1;
                    }
                }
            }
            //入队
            for(int i = 0 ; i < k;i++)
            {
                //如果窗口无人
                if(window[i] == -1)
                {
                    //判断顾客是否来过
                    if(c[next].come_time <= 17 * 3600 && c[next].come_time <= time)
                    {
                        window[i] = next;
                        next++;
                    }
                }
            }
            //迎客
            for(int i = 0 ; i < k;i++)
            {
                if(window[i] >= 0)
                {
                    int j = window[i];
                    if(c[j].leave_time == 0)
                    {
                        sum += time - c[j].come_time;
                        c[j].leave_time = time + c[j].process_time;
                    }
                }
            }
        }
        System.out.printf("%.1f",sum / next / 60);
    }
}
class customer{
    int come_time,process_time,leave_time = 0;
    public customer()
    {

    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值