2024年华为OD笔试机试E卷- 高矮个子排队 (java/c++/python)

华为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("[]")


矮个子排队是一个常见的问题,在解决这个问题的过程中,我们需要确定一个规则,以便能够有序地排列身。对于这个问题,我会采用以下方法来解决。 首先,我们可以将所有的人按照身进行排序。可以采用冒泡排序、插入排序或者快速排序等方法,根据具体情况选择最适合的排序算法。排序结束后,就可以得到一个按照身从低到排列的队列。 接下来,我们可以根据身分配编号,较矮者编号较小,较者编号较大。可以将身从低到依次进行编号,编号可以从1开始。这样,每个人就有了一个唯一的编号。 最后,按照编号的顺序,将所有的人重新排列。这样,就可以得到一个按照身从低到有序排列的队列。 需要注意的是,在实际操作中,我们可能会遇到一些特殊情况,例如身相同的人如何处理。在这种情况下,我们可以根据其他属性来进一步排序,例如按照体重、龄等属性进行排序。当然,如果其他属性也相同,我们可以采取随机分配的方法来决定排列顺序。 综上所述,解决矮个子排队问题的关键在于确定一个合适的规则,并按照规则进行排序和排队。通过合理的规划和操作,我们就可以得到一个满足要求的排队队列。这样不仅可以实现矮个子的有序排列,也体现了对每个人的公平对待。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值