【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【排序】2024E-预订酒店【欧弟算法】全网注释最详细分类最全的华为OD真题题解

可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 oj1441了解算法冲刺训练(备注【CSDN】否则不通过)

相关推荐阅读

从2024年8月14号开始,OD机考全部配置为2024E卷
注意几个关键点:

  1. 大部分的题目仍为往期2023A+B+C以及2024D的旧题。注意万变不离其宗,把方法掌握,无论遇到什么题目都可以轻松应对。
  2. 支持多次提交题目,以最后一次提交为准。可以先做200的再做100的,然后可以反复提交。
  3. E卷仍然为单机位+屏幕监控的形式进行监考。
  4. 进入考试界面新加入了这样一段话并且用红字标出,可以看出华子对作弊代考等行为是0容忍的,请各位同学认真学习,不要妄图通过其他违规途径通过考试。
    在这里插入图片描述

题目描述与示例

题目描述

放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店(n >= k > 0),并由低到高打印酒店的价格。

输入描述

第一行:n k x 第二行:A[0] A[1] A[2]…A[n-1]

输出描述

从低到高打印筛选出的酒店价格

示例一

输入

10 5 6
1 2 3 4 5 6 7 8 9 10

输出

4 5 6 7 8

示例二

输入

10 4 6
10 9 8 7 6 5 4 3 2 1

输出

4 5 6 7

示例三

输入

6 3 1000
30 30 200 500 70 300

输出

200 300 500

解题思路

非常水的排序题,直接使用lambda函数排序即可。

由于距离心理价位x最近的价格,因此排序依据是abs(num-x)

【排序】2024D-身高排序非常类似。

在使用lambda函数的时候,要特别注意一点,需要这样进行排序

# 优先按照价格num到心理价位x的距离abs(num-x)来排序
# 当距离一致时,需要按照num从小到大排序
nums.sort(key = lambda num: (abs(num-x), num))

而不是

nums.sort(key = lambda num: abs(num-x))

他们的区别在于,在当两个元素num1num2x的距离相等时,前者会按照num1num2的大小关系从小到大排列,后者会按照num1num2在原数组中的前后位置进行排列。

从示例二可以看出,对于例子

10 4 6
10 9 8 7 6 5 4 3 2 1

要得到的结果是

4 5 6 7

而不是

5 6 7 8

这是因为,原数组中的48都是距离心理价位6距离为2的元素。

根据题目要求,我们可以得知输出中的第四个元素应该是大小更小的4,而不是在原数组中位置更靠前的8,因此我们在做第一次排序的时候,必须使用第一种排序方法来排序。

代码

python

# 题目:【模拟】2024E-预定酒店
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:模拟,排序
# 代码看不懂的地方,请直接在群上提问


# 输入数组长度n,输出数组长度k,心理价位x,
n, k, x = map(int, input().split())
# 输入数组
nums = list(map(int, input().split()))
# 优先按照价格num到心理价位x的距离abs(num-x)来排序
# 当距离一致时,需要按照num从小到大排序
nums.sort(key = lambda num: (abs(num-x), num))
# 取排序后的nums数组中的前k个,作为答案列表
ans = nums[:k]
# ans中元素再按照从小到大排序
ans.sort()
# 输出结果
print(" ".join(map(str, ans)))

java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 输入数组长度n,输出数组长度k,心理价位x,
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int x = scanner.nextInt();

        // 输入数组
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }

        // 将数组转换为列表以便排序
        List<Integer> numsList = new ArrayList<>();
        for (int num : nums) {
            numsList.add(num);
        }

        // 优先按照价格num到心理价位x的距离abs(num-x)来排序
        // 当距离一致时,需要按照num从小到大排序
        Collections.sort(numsList, new Comparator<Integer>() {
            @Override
            public int compare(Integer num1, Integer num2) {
                int diff1 = Math.abs(num1 - x);
                int diff2 = Math.abs(num2 - x);
                if (diff1 != diff2) {
                    return diff1 - diff2;
                } else {
                    return num1 - num2;
                }
            }
        });

        // 取排序后的nums数组中的前k个,作为答案列表
        List<Integer> ans = new ArrayList<>(numsList.subList(0, k));

        // ans中元素再按照从小到大排序
        Collections.sort(ans);

        // 输出结果
        for (int i = 0; i < ans.size(); i++) {
            System.out.print(ans.get(i));
            if (i != ans.size() - 1) {
                System.out.print(" ");
            }
        }
    }
}

cpp

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath> // for abs

using namespace std;

int main() {
    // 输入数组长度n,输出数组长度k,心理价位x,
    int n, k, x;
    cin >> n >> k >> x;

    // 输入数组
    vector<int> nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }

    // 优先按照价格num到心理价位x的距离abs(num-x)来排序
    // 当距离一致时,需要按照num从小到大排序
    sort(nums.begin(), nums.end(), [x](int num1, int num2) {
        int diff1 = abs(num1 - x);
        int diff2 = abs(num2 - x);
        if (diff1 != diff2) {
            return diff1 < diff2;
        } else {
            return num1 < num2;
        }
    });

    // 取排序后的nums数组中的前k个,作为答案列表
    vector<int> ans(nums.begin(), nums.begin() + k);

    // ans中元素再按照从小到大排序
    sort(ans.begin(), ans.end());

    // 输出结果
    for (size_t i = 0; i < ans.size(); i++) {
        cout << ans[i];
        if (i != ans.size() - 1) {
            cout << " ";
        }
    }

    return 0;
}

时空复杂度

时间复杂度:O(NlogN)

空间复杂度:O(1)


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

闭着眼睛学算法

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

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

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

打赏作者

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

抵扣说明:

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

余额充值