【华为OD机试真题 2022&2023】真题目录 @点这里@
【华为OD机试真题】信号发射和接收 &试读& @点这里@
【华为OD机试真题】租车骑绿道 &试读& @点这里@
租车骑绿道
部门组织绿岛骑行团建活动。租用公共双人自行车,每辆自行车最多坐两人,做最大载重M。给出部门每个人的体重,请问最多需要租用多少双人自行车。
输入描述:
第一行两个数字m、n,分别代表自行车限重,部门总人数。
第二行,n个数字,代表每个人的体重,体重都小于等于自行车限重m。
0<m<=200
0<n<=1000000
输出描述:
最小需要的双人自行车数量。
示例1
输入:
3 4
3 2 2 1
输出:
3
解题思路:
1:题目中有两个隐含的条件:
- 一辆车最多骑两个人
- 人的重量不可能大于车的载重
2:那么可以用两个指针,一个指向头部left,一个指向尾部right,如果w【left】+w【right】>车的载重,那么意味着最重的人,加上最轻的人都会超载,只能他一个人骑,right–。
如果w【left】 + w【right】<=车的载重,那么意味着这两个人可以还可以再加人,left ++继续判断直到总重量>车的载重。
C语言代码:
代码解读:
给定的代码是一个解决问题的解决方案,该问题需要找到运输一组人所需的最少自行车数量,给定他们的重量和自行车的最大重量容量。代码首先读取输入值m和n,其中m是自行车的最大重量容量,n是人数。然后它读取每个人的重量并使用冒泡排序算法按升序对它们进行排序。
代码然后将两个指针left和right初始化为已排序的重量数组的第一个和最后一个索引,分别。它还将变量minbikes初始化为0,该变量将跟踪所需的最少自行车数量。然后,代码进入一个循环,直到左指针大于或等于右指针为止。在循环内部,代码检查左指针和右指针处的重量之和是否大于m。如果是,则将右指针递减以选择较轻的人。如果不是,则左右指针都递增和递减,以选择较重和较轻的人。然后计算新左右指针处的重量总和,循环继续。
循环结束后,代码检查左右指针是否相等。如果它们相等,则意味着还有一个人没有被分配到自行车上,因此minbikes会递增。最后,代码打印出minbikes的值。
总体而言,代码正确实现了所需的算法,以找到运输一组人所需的最少自行车数量。用于对重量进行排序的冒泡排序算法不是最有效的排序算法,但对于此问题中使用的小输入大小而言,它是简单且足够的。
#include<stdio.h>
void bubble_sort(int arr[], int n) {
int i, j, temp;
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main() {
// 处理输入
int m,n;
scanf("%d %d", &m, &n);
int weights[n];
for (int i=0;i<n;i++) {
scanf("%d", &weights[i]);
}
//第一步,排序
bubble_sort(weights, n); // 对人的重量进行排序,从小到大
//第二步,左右指针向中间移动
int left=0; // 左指针指向最轻的人
int right = n-1; // 右指针指向最重的人
//结果
int min_bikes = 0; // 最少需要的车的数量
//当前重量
int temp_weight = weights[right] + weights[left]; // 当前两个人的重量
// 题目中有两个隐含的条件
// 1: 一辆车最多骑两个人
// 2:人的重量不可能大于车的载重
for (; left<right; min_bikes++) { // 当左指针小于右指针时,继续循环
if (temp_weight > m) { // 如果当前两个人的重量大于车的载重
right --; // 右指针向左移动,即选择一个更轻的人
} else{
right --; // 右指针向左移动,即选择一个更轻的人
left ++; // 左指针向右移动,即选择一个更重的人
}
temp_weight = weights[right] + weights[left]; // 更新当前两个人的重量
}
if (left == right) { // 如果左指针等于右指针,说明还有一个人没有被分配到车上
min_bikes++; // 需要再增加一辆车
}
printf("%d\n", min_bikes); // 输出最少需要的车的数量
return 0;
}