个人博客首页: 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
输出
运行结果输出一个整数 ,表示中转车统一限载货物数
备注
中转车最多跑一趟仓库
输入
4
3 2 6 3
0 1 1 0
2
输出
6
说明
货物1和货物4为干货,由2辆干货中转车中转,每辆车运输一个货物,限载为3
货物2和货物3为湿货,由2辆湿货中转车中转,每辆车运输一个货物,限载为6
这样中转车统一限载货物数可以设置为6 (干货车和湿货车限载最大值),是 最小的取值
输入
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;
}