华为OD机试E卷2024真题目录(java & c++ & python)
本人习惯先看输入输出描述,可以明确知道哪些数据已知,需要去得到什么结果,再代入更有目的性地阅读题干内容,快速理解,所以把输入输出描述放在前面,你可以试下这样阅读对你是否有帮助。
输入描述
排序前的小朋友,以英文空格的正整数:
4 3 5 7 8
注:小朋友<100个
输出描述
排序后的小朋友,以英文空格分割的正整数:4 3 7 5 8
备注:4(高)3(矮)7(高)5(矮)8(高), 输出结果为最小移动距离,只有5和7交换了位置,移动距离都是1。
题目描述
现在有一队小朋友,他们高矮不同,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。
我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,每一个“高”位置的小朋友要比相邻的位置高或者相等;每一个“矮”位置的小朋友要比相邻的位置矮或者相等;
要求小朋友们移动的距离和最小,第一个从“高”位开始排,输出最小移动距离即可。
例如,在示范小队{5,3,1,2,3}中,{5, 1, 3, 2, 3}是排序结果。
{5, 2, 3, 1, 3} 虽然也满足“高”“矮”“高”“矮”顺序排列,但小朋友们的移动距离大,所以不是最优结果。
移动距离的定义如下所示:
第二位小朋友移到第三位小朋友后面,移动距离为1,若移动到第四位小朋友后面,移动距离为2;
用例1
输入
4 1 3 5 2
输出
4 1 5 2 3
用例2
输入
1 1 1 1 1
输出
1 1 1 1 1
说明 相邻位置可以相等
用例3
输入
xxx
输出
[]
说明 出现非法参数情况, 返回空数组。
解题思路
分析用例1可以看出,实际是按顺序从左到右,每当遇到不符合要求的排队顺序,就必须交换位置。
否则只交换5 和 2 才是最小移动距离。按照用例来执行逻辑即可。
C++、Java、Python参考代码如下:
Java
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;
public class Main {
// 主函数,程序入口
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
// 读取输入并转换为整数数组
int[] nums = Arrays.stream(sc.nextLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray();
// 对数组进行交替比较与交换
for (int i = 0; i < nums.length - 1; i++) {
// 根据当前索引判断是否需要交换
boolean needSwap = (i % 2 == 0) ? nums[i] < nums[i + 1] : nums[i] > nums[i + 1];
// 如果需要交换,则进行交换
if (needSwap) {
int temp = nums[i];
nums[i] = nums[i + 1];
nums[i + 1] = temp;
}
}
// 使用 StringJoiner 构建输出字符串
StringJoiner sj = new StringJoiner(" ");
for (int num : nums) {
sj.add(String.valueOf(num)); // 将数字转换为字符串并添加到 Joiner
}
// 输出结果
System.out.println(sj.toString());
} catch (Exception e) {
// 异常处理,输出空数组
System.out.println("[]");
}
}
}
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> nums; // 存储输入的整数
string input;
while (cin >> input) {
// 检查输入是否都是数字
for (const auto &ch : input) {
if (!isdigit(ch)) {
cout << "[]" << endl; // 如果有非数字字符,输出空数组
return 0;
}
}
// 将字符串转换为整数并添加到数组中
nums.emplace_back(stoi(input));
}
// 对输入的整数进行交错排序
for (int i = 0; i < nums.size() - 1; i++) {
// 判断当前索引的元素与下一个元素是否需要交换
bool needSwap = (i % 2 == 0) ? (nums[i] < nums[i + 1]) : (nums[i] > nums[i + 1]);
if (needSwap) {
// 交换元素
swap(nums[i], nums[i + 1]);
}
}
// 输出结果
for (int num : nums) {
cout << num << " ";
}
cout << endl; // 输出换行符
return 0;
}
Python
try:
# 从输入中读取数字并转换为整数列表
nums = list(map(int, input().split()))
# 遍历列表的索引
for i in range(len(nums) - 1):
# 判断当前索引的奇偶性来决定是否需要交换
needSwap = nums[i] < nums[i + 1] if i % 2 == 0 else nums[i] > nums[i + 1]
# 如果需要交换,则进行交换
if needSwap:
nums[i], nums[i + 1] = nums[i + 1], nums[i]
# 输出处理后的结果,使用空格连接
print(" ".join(map(str, nums)))
# 捕捉输入转换过程中可能发生的异常
except ValueError:
print("[]")