华为OD2023(A卷)基础题【7核酸检测】

【优选核酸检测点】

张三要去外地出差,需要做核酸,需要在指定时间点前做完核酸,
请帮他找到满足条件的核酸检测点。
给出一组核酸检测点的距离和每个核酸检测点当前的人数
给出张三要去做核酸的出发时间 出发时间是10分钟的倍数
同时给出张三做核酸的最晚结束时间
题目中给出的距离是整数,单位是公里,时间1分钟为一基本单位
去找核酸点时,有如下的限制:

  1. 去往核酸点的路上,每公里距离花费时间10分钟,费用是10元
  2. 核酸点每检测一个人的时间花费是1分钟
  3. 每个核酸点工作时间都是8点到20点中间不休息,核酸点准时工作,早到晚到都不检测
  4. 核酸检测结果可立刻知道
  5. 在张三去某个核酸点的路上花费的时间内,此核酸检测点的人数是动态变化的,变化规则是
    1).在非核酸检测时间内,没有人排队
    2).8点-10点每分钟增加3人
    3).12点-14点每分钟增加10人
    4).18点-20点每分钟增加20人
    5).其他时间每5分钟增加1人。

要求将所有满足条件的核酸检测点按照优选规则排序列出优选规则:
1.花费时间最少的核酸检测点排在前面
2.花费时间一样花费费用最少的核酸检测点排在前面
3.时间和费用一样,则ID值最小的排在前面

输入描述
H1 M1
H2 M2
N
ID1 D1 C1
ID2 D2 C2

IDn Dn Cn

H1: 当前时间的小时数
M1: 当前时间的分钟数
H2:指定完成核算时间的小时数
M2: 指定完成核算时间的分钟数
N: 所有核酸检测点个数。
ID1: 核酸点的ID值。
D1:核酸检测点距离张三的距离
C1:核酸检测点当前检测的人数

输出描述
N
12 T2 M2
13 T3 M3
N: 满足要求的核酸检测点个数
I2:选择后的核酸检测点ID
T2·做完核酸花费的总时间(分钟)
M3:去该核算点花费的费用
华为OD2023(A卷)基础题【7核酸检测】_第1张图片

Java代码:

/**
 *
 代码说明:
 1. 核酸检测点实体类(Node):记录了核酸点的ID值、距离张三的距离、当前检测的人数、以及张三在该核酸检测点花费的时间和费用。
 2. getResult()方法:计算从张三出发到每个核酸检测点需要花费的时间和费用,如果去该核酸检测点的时间已经超过了指定完成核算时间,
 就不考虑该核酸检测点。如果可以去该核酸检测点,则记录该核酸检测点的花费时间和费用,并将其加入到结果列表中。
 最后按照优选规则排序列出结果。
 3. getTimeDiff()方法:计算从当前时间出发,到指定完成核算时间的剩余时间(单位:分钟)。
 4. getWaitTime()方法:根据当前时间、从张三处出发到该核酸检测点所需要的时间、以及在该核酸检测点排队等待检测的人数
 ,计算在该核酸检测点排队等待检测所需要的时间(单位:分钟)。
 */
public class OdAb7 {
    public void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h1 = sc.nextInt(); // 当前时间的小时数
        int m1 = sc.nextInt(); // 当前时间的分钟数
        int h2 = sc.nextInt(); // 指定完成核酸时间的小时数
        int m2 = sc.nextInt(); // 指定完成核酸时间的分钟数
        int n = sc.nextInt();  // 核酸检测点的数量

        List<Node> nodeList = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int id = sc.nextInt();  // 核酸点ID值
            int d = sc.nextInt();   // 核酸点距离张三的距离
            int c = sc.nextInt();   // 核酸点当前检测的人数
            nodeList.add(new Node(id, d, c));
        }

        sc.close();

        // 将所有满足条件的核酸检测点按照优选规则排序列出
        List<Node> result = getResult(h1, m1, h2, m2, nodeList);

        // 输出结果
        System.out.println(result.size());
        for (Node node : result) {
            System.out.println(node.getId() + " " + node.getCostTime() / 60 + " " + node.getCostTime() % 60);
        }
    }

    /**
     * 获取满足条件的核酸检测点
     *
     * @param h1       当前时间的小时数
     * @param m1       当前时间的分钟数
     * @param h2       指定完成核算时间的小时数
     * @param m2       指定完成核算时间的分钟数
     * @param nodeList 核酸检测点列表
     * @return 满足条件的核酸检测点列表
     */
    private static List<Node> getResult(int h1, int m1, int h2, int m2, List<Node> nodeList) {
        List<Node> result = new ArrayList<>();
        for (Node node : nodeList) {
            // 计算从张三出发到该核酸检测点需要花费的时间和费用
            int distance = node.getDistance();
            int costTime = distance * 10;
            int costMoney = distance * 10;

            // 算上在核酸检测点排队等待检测的时间
            int waitTime = getWaitTime(h1, m1, costTime, node.getPeopleNum());
            if (waitTime + costTime > getTimeDiff(h1, m1, h2, m2)) {
                // 如果去该核酸检测点时间已经超过了指定完成核算时间,就不考虑该核酸检测点
                continue;
            }
            costTime += waitTime;
            costMoney += waitTime * 6; // 等待过程中每分钟花费6元

            // 记录该核酸检测点的最终花费时间和费用
            node.setCostTime(costTime);
            node.setCostMoney(costMoney);
            result.add(node);
        }

        // 按照优选规则排序列出
        result.sort(new Comparator<Node>() {
            @Override
            public int compare(Node n1, Node n2) {
                // 1. 花费时间最少的核酸检测点排在前面
                if (n1.getCostTime() != n2.getCostTime()) {
                    return n1.getCostTime() - n2.getCostTime();
                }
                // 2. 花费时间一样花费费用最少的核酸检测点排在前面
                if (n1.getCostMoney() != n2.getCostMoney()) {
                    return n1.getCostMoney() - n2.getCostMoney();
                }
                // 3. 时间和费用一样,则ID值最小的排在
                return n1.getId() - n2.getId();
            }
        });

        return result;
    }

    /**
     * 获取从当前时间出发,到指定完成核算时间的剩余时间(单位:分钟)
     *
     * @param h1 当前时间的小时数
     * @param m1 当前时间的分钟数
     * @param h2 指定完成核算时间的小时数
     * @param m2 指定完成核算时间的分钟数
     * @return 从当前时间出发,到指定完成核算时间的剩余时间(单位:分钟)
     */
    private static int getTimeDiff(int h1, int m1, int h2, int m2) {
        return (h2 - h1) * 60 + m2 - m1;
    }

    /**
     * 获取在该核酸检测点排队等待检测所需要的时间(单位:分钟)
     * 假设每个人检测需要10分钟,如果有n个人在排队,则需要花费10*n分钟。
     *
     * @param h   当前时间的小时数
     * @param m   当前时间的分钟数
     * @param t   从张三处出发到该核酸检测点所需要的时间(单位:分钟)
     * @param num 在该核酸检测点排队等待检测的人数
     * @return 在该核酸检测点排队等待检测所需要的时间(单位:分钟)
     */
    private static int getWaitTime(int h, int m, int t, int num) {
        int arriveTime = (h * 60 + m + t) % (24 * 60); // 张三到达该核酸检测点的时间(单位:分钟)
        int startTime = Math.max(arriveTime, 8 * 60);   // 核酸检测点开始工作的时间是8:00,如果张三到达的时间比这个时间早,就从8:00开始计算等待时间
        return (startTime - arriveTime) + 10 * num;     // 等待过程中每人需要花费10分钟
    }

    /**
     * 核酸检测点实体类
     */
    class Node {
        private int id;         // 核酸点ID值
        private int distance;   // 核酸点距离张三的距离
        private int peopleNum;  // 核酸点当前检测的人数
        private int costTime;   // 张三在该核酸检测点花费的时间(单位:分钟)
        private int costMoney;  // 张三在该核酸检测点花费的费用

        public Node(int id, int distance, int peopleNum) {
            this.id = id;
            this.distance = distance;
            this.peopleNum = peopleNum;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getDistance() {
            return distance;
        }

        public void setDistance(int distance) {
            this.distance = distance;
        }

        public int getPeopleNum() {
            return peopleNum;
        }

        public void setPeopleNum(int peopleNum) {
            this.peopleNum = peopleNum;
        }

        public int getCostTime() {
            return costTime;
        }

        public void setCostTime(int costTime) {
            this.costTime = costTime;
        }

        public int getCostMoney() {
            return costMoney;
        }

        public void setCostMoney(int costMoney) {
            this.costMoney = costMoney;
        }
    }

}```

你可能感兴趣的:(华为od,算法,java)