【华为机试真题详解 Java实现】统一限载货物数最小值【2023 Q1 考试题 A卷 200分】

这是一篇关于华为机试真题的解析,主要讨论如何确定在满足干湿货物不混装及中转车限制条件下,最小的货物限载数值。解题思路涉及对干货和湿货的货物数量、最大货物数量的计算,以及使用二分查找法确定最小限载量。文章提供了问题描述、输入输出规格以及参考代码。
摘要由CSDN通过智能技术生成

题目描述

【统一限载货物数最小值】

火车站附近的货物中转站负责将到站货物运往仓库,小明在中转站负责调度2K辆中转车(K辆干货中转车,K辆湿货中转车)。
货物由不同供货商从各地发来,各地的货物是依次进站,然后小明按照卸货顺序依次装货到中转车上,一个供货商的货只能装到一辆车上,
不能拆装,但是一辆车可以装多家供货商的货;
中转车的限载货物量由小明统一制定,在完成货物中转的前提下,请问中转车的统一限载货物数最小值为多少。

输入描述

第一行length表示供货商数量 1 <= length <= 10^4

第二行goods表示供货数数组 1 <= goods[i] <= 10^4

第三行types表示对应货物类型,types[i]等于0或者1,0代表干货,1代表湿货

第四行k表示单类中转车数量1 <= k <= goods.length

输出描述

一个整数,表示中转车统一限载货物数

补充说明

中转车最多跑一趟仓库
干湿货物不能混装

解题思路

首先按照干货和湿货分别计算总货物数量,同时记录下其中最大的单个货物数量。然后根据单类中转车的数量,计算出干货和湿货的最小限载量,最终取其最大值作为最终的限载量的上限。

接下来,利用二分查找法找到符合条件的最小限载量。在二分查找过程中,每次计算出干货和湿货需要的中转车数量,判断总车数是否小于等于2k,并且最大货物数量是否小于等于限制值,根据这些条件移动左右指针,最终得到最小限载量。

时间复杂度:O(NlogM),其中 N 为货物数量,M 为货物总重量的上限,因为使用了二分查找,最多进行 logM 次操作。

空间复杂度:O(N),需要存储货物重量和湿/干属性。

参考代码

import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读入数据长度
        int length = scanner.nextInt();
        // 初始化货物数组和类型数组
        int[] goods = new int[length];
        int[] types = new int[length];
        // 读入货物数组和类型数组
        for (int i = 0; i < length; i++) {
            goods[i] = scanner.nextInt();
        }
        for (int i = 0; i < length; i++) {
            types[i] = scanner.nextInt();
        }
        // 读入中转车数量上限
        int k = scanner.nextInt();

        // 统计干货和湿货的总数和最大货物重量
        int totalDryGoods = 0;
        int totalWetGoods = 0;
        int maxGoods = 0;
        for (int i = 0; i < length; i++) {
            if (types[i] == 0) {
                totalDryGoods += goods[i];
                maxGoods = Math.max(maxGoods, goods[i]);
            } else {
                totalWetGoods += goods[i];
                maxGoods = Math.max(maxGoods, goods[i]);
            }
        }

        // 计算干货和湿货的中转车上限
        int maxDryGoods = totalDryGoods / k;
        if (totalDryGoods % k != 0) {
            maxDryGoods++;
        }
        int maxWetGoods = totalWetGoods / k;
        if (totalWetGoods % k != 0) {
            maxWetGoods++;
        }
        // 求干货和湿货的中转车上限的最大值
        int maxLimit = Math.max(maxDryGoods, maxWetGoods);

        // 二分查找,找到符合要求的最小中转车载重
        int left = maxLimit;
        int right = totalDryGoods + totalWetGoods;
        while (left < right) {
            int mid = (left + right) / 2;

            // 计算干货和湿货需要的中转车数量
            int numDryCars = getNumCars(totalDryGoods, mid);
            int numWetCars = getNumCars(totalWetGoods, mid);

            // 如果总中转车数量不超过上限,且最大货物重量不超过中转车载重,说明满足条件
            if (numDryCars + numWetCars <= 2 * k && maxGoods <= mid) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }

        // 输出符合条件的最小中转车载重
        System.out.println(left);
    }

    // 计算所需的中转车数量
    private static int getNumCars(int totalGoods, int limit) {
        int numCars = totalGoods / limit;
        if (totalGoods % limit != 0) {
            numCars++;
        }
        return numCars;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值