【华为OD机试真题 C语言】54、统一限载货物数最小值 | 机试真题+思路参考+代码解析

文章目录

    • 一、题目
      • 题目描述
      • 输入输出
      • 样例1
      • 样例2
    • 二、思路参考
    • 三、代码参考
  • 作者:KJ.JK


个人博客首页: KJ.JK
 
专栏介绍: 华为OD机试真题汇总,定期更新华为OD各个时间阶段的机试真题,每日定时更新,本专栏将使用C语言进行更新解答,包含真题,思路分析,代码参考,欢迎大家订阅学习


一、题目


题目描述

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


输入输出

输入
第一行 length表示供货商数量1 <= length <= 10^4
第二行 goods表示供货数数组1 <= goods[j] <= 10^4
第三行 types表示对应货物类型, types[jI等于0或者1, 其中0代表干货,,1代表湿货
第四行k表示单类中转车数量1 <= k <= goods.length
 
输出
运行结果输出一个整数 ,表示中转车统一限载货物数
 
备注
中转车最多跑一趟仓库


样例1

输入
4
3 2 6 3
0 1 1 0
2

输出
6

说明
货物1和货物4为干货,由2辆干货中转车中转,每辆车运输一个货物,限载为3

货物2和货物3为湿货,由2辆湿货中转车中转,每辆车运输一个货物,限载为6

这样中转车统一限载货物数可以设置为6 (干货车和湿货车限载最大值),是 最小的取值

样例2

输入
4
3 2 6 8
0 1 1 1
1

输出
16

说明
货物1为干货,由1辆干货中转车中转,限载为3
货物2、货物3、货物4为湿货,由1辆湿货中转车中转,限载为16
这样中转车统一限载货物数可以设置为16 (干货车和湿货车限载最大值) , 是最小的取值

二、思路参考

首先,根据输入,获取供货商的数量(len)、每个供货商的货物数量(goods数组)和货物类型(types数组)以及单类中转车的数量(k)。

使用循环遍历货物数组,找到货物数量的最大值作为初始化的左边界(left),同时累加所有货物数量得到初始化的右边界(right)。

进入一个循环,直到左边界小于右边界。在循环中,计算当前的中间值(mid)作为限载量的候选值。

调用canDivide函数判断是否可以按照给定限制分配货物,传递供货商数量、货物数组、货物类型、单类中转车数量以及限载量作为参数。该函数根据以下规则进行判断:

对于干货(类型为0),检查当前干货总量是否小于等于限载量,如果是,则将干货数量累加到干货总量中;否则,检查是否还有可用的干货车辆,如果没有,则返回0表示无法完成所有货物的运输;如果有,则增加干货车辆数量,并将当前干货数量赋值给干货总量。
对于湿货(类型为1),按照类似的逻辑进行判断。
如果canDivide函数返回1,表示可以按照给定限制分配货物,将右边界更新为当前中间值;否则,将左边界更新为当前中间值加1。

循环结束后,左边界的值就是中转车的统一限载货物数,将其返回。

在main函数中,根据输入获取相应的数据,并调用getResult函数来计算中转车的统一限载货物数。最后,将结果打印输出。

总体而言,该代码使用二分查找算法来确定最小的可行限载量,通过判断是否可以按照给定限制分配货物来更新搜索区间,直到找到最小的可行限载量为止。

三、代码参考

#include 
int canDivide(int len, int* goods, int* types, int k, int limit);
// 计算中转车的统一限载货物数
int getResult(int len, int* goods, int* types, int k) {
    int left = 0;
    int right = 0;
    for (int i = 0; i < len; i++) {
        left = (left > goods[i]) ? left : goods[i];
        right += goods[i];
    }

    while (left < right) {
        int mid = (left + right) / 2;
        if (canDivide(len, goods, types, k, mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}

// 判断是否可以按照给定限制分配货物
int canDivide(int len, int* goods, int* types, int k, int limit) {
    int dryCount = 0;
    int wetCount = 0;
    int drySum = 0;
    int wetSum = 0;

    for (int i = 0; i < len; i++) {
        // 0-干货,1-湿货
        if (types[i] == 0) {
            // 判断当前干货是否可以装入车辆
            if (drySum + goods[i] <= limit) {
                drySum += goods[i];
            } else {
                // 超过限载容量,检查是否还有可用的干货车辆
                if (dryCount + 1 == k) {
                    return 0; // 返回0表示无法完成所有货物的运输
                } else {
                    dryCount++;
                    drySum = goods[i];
                }
            }
        } else {
            // 判断当前湿货是否可以装入车辆
            if (wetSum + goods[i] <= limit) {
                wetSum += goods[i];
            } else {
                // 超过限载容量,检查是否还有可用的湿货车辆
                if (wetCount + 1 == k) {
                    return 0; // 返回0表示无法完成所有货物的运输
                } else {
                    wetCount++;
                    wetSum = goods[i];
                }
            }
        }
    }
    return 1; // 返回1表示可以按照给定限制分配货物
}

int main() {
    int len; // 供货商数量
    scanf("%d", &len);

    int goods[len]; // 供货数数组
    for (int i = 0; i < len; i++) {
        scanf("%d", &goods[i]);
    }

    int types[len]; // 货物类型数组
    for (int i = 0; i < len; i++) {
        scanf("%d", &types[i]);
    }

    int k; // 单类中转车数量
    scanf("%d", &k);

    // 调用计算函数获取中转车的统一限载货物数
    int result = getResult(len, goods, types, k);

    // 输出结果
    printf("%d\n", result);

    return 0;
}


作者:KJ.JK

你可能感兴趣的:(华为OD机试真题(C语言),华为od,c语言,华为,华为OD机试真题,统一限载货物数最小值)