华为笔试 华为笔试题 0507

笔试时间:2025年5月7日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:寻找智能汽车行驶距离最近的K个充电桩

一个超大智能汽车测试场有多个充电桩,每个充电桩的位置由其在二维平面上的坐标 (x, y) 表示。给定一辆智能汽车的当前位置 (car_x, car_y),请设计一个高效的算法,找出给定智能汽车行驶到充电桩行驶距离最近的k个充电桩并输出相关充电桩信息(编号、坐标、行驶距离),且按行驶距离升序排序(最近行驶距离的排在最前面),如果存在行驶距离相等的充电桩则按照充电桩的编号从小到大输出。汽车到充电桩的行驶距离的计算方法为 abs(car_x - x) + abs(car_y - y) 注意:abs表示绝对值。

输入描述

第一行是2个整数k n,空格间隔,第1个整数k表示需要输出到的行驶距离最近的充电桩的数量( 0 <= k <= 1000000),第2个整数n表示充电桩的总数量(0 < n <= 1000000)。

第2行是长度为2的整数数组car_x car_y,中间是空格间隔,表示智能汽车的当前位置坐标。

第3行到第n+2行是编号为1到n的充电桩的位置坐标。

注意:坐标数值大小区间为: [-2^32, 2^31-1]

输出描述

一个二维数组,每一行是一个长度为4 的数组:编号 x y distance,编号表示充电桩的编号(介于1到n之间)、x y表示充电桩的坐标, distance表示智能汽车到充电桩的行驶距离,从第1行开始往下是按距离从小到大排序的。 如果存在行驶距离相等的充电桩则按照充电桩的编号从小到大输出。如果k为0或者k大于n,输出字符串null。

样例输入

3 5 

0 0 

1 4 

5 6 

2 3 

7 8 

3 -1

样例输出

5 3 -1 4 

1 1 4 5 

3 2 3 5

解释:到汽车行驶距离最近的三个充电桩的编号分别为5、1、3,充电桩的坐标分别是3 -1、1 4、2 3,到智能汽车坐标[0,0]的行驶距离分别为4、5、5。距离都为5的充电桩1的编号小于编号3的充电桩,输出结果中编号小的在前。

参考题解

数据存储与预处理使用结构体存储每个充电桩的编号、坐标和曼哈顿距离,计算公式为 distance = |car_x - x| + |car_y - y|。所有充电桩信息存入数组,时间复杂度为 *O(n)*。排序策略对充电桩数组进行排序,排序规则为:优先按距离从小到大排序若距离相同,则按编号从小到大排序使用快速排序算法。边界处理若 k=0 或 k>n,直接输出 null;否则截取排序后的前k个元素输出。

C++:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main() {
    vector<string> input;
    string token;
    while (cin >> token) {
        input.push_back(token);
    }
    
    int ptr = 0;
    int k = stoi(input[ptr++]);
    int n = stoi(input[ptr++]);
    
    if (k == 0 || k > n) {
        cout << "null" << endl;
        return 0;
    }
    
    int car_x = stoi(input[ptr++]);
    int car_y = stoi(input[ptr++]);
    
    vector<tuple<int, int, int, int>> chargers;
    for (int i = 0; i < n; i++) {
        int x = stoi(input[ptr++]);
        int y = stoi(input[ptr++]);
        int distance = abs(car_x - x) + abs(car_y - y);
        chargers.push_back(make_tuple(distance, i+1, x, y));
    }
    
    sort(chargers.begin(), chargers.end(), [](const auto& a, const auto& b) {
        if (get<0>(a) != get<0>(b))
            return get<0>(a) < get<0>(b);
        return get<1>(a) < get<1>(b);
    });
    
    for (int i = 0; i < k; i++) {
        auto [d, idx, x, y] = chargers[i];
        cout << idx << " " << x << " " << y << " " << d << endl;
    }
    
    return 0;
}

Java:

import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<String> input = new ArrayList<>();
        while (scanner.hasNext()) {
            input.add(scanner.next());
        }
        
        int ptr = 0;
        int k = Integer.parseInt(input.get(ptr++));
        int n = Integer.parseInt(input.get(ptr++));
        
        if (k == 0 || k > n) {
            System.out.println("null");
            return;
        }
        
        int car_x = Integer.parseInt(input.get(ptr++));
        int car_y = Integer.parseInt(input.get(ptr++));
        
        List<Charger> chargers = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int x = Integer.parseInt(input.get(ptr++));
            int y = Integer.parseInt(input.get(ptr++));
            int distance = Math.abs(car_x - x) + Math.abs(car_y - y);
            chargers.add(new Charger(distance, i+1, x, y));
        }
        
        Collections.sort(chargers, (a, b) -> {
            if (a.distance != b.distance)
                return a.distance - b.distance;
            return a.idx - b.idx;
        });
        
        for (int i = 0; i < k; i++) {
            Charger c = chargers.get(i);
            System.out.printf("%d %d %d %d%n", c.idx, c.x, c.y, c.distance);
        }
    }
    
    static class Charger {
        int distance;
        int idx;
        int x;
        int y;
        
        Charger(int distance, int idx, int x, int y) {
            this.distance = distance;
            this.idx = idx;
            this.x = x;
            this.y = y;
        }
    }
}

Python:

import sys

def main():
    input = sys.stdin.read().split()
    ptr = 0
    k = int(input[ptr])
    ptr +=1
    n = int(input[ptr])
    ptr +=1
    
    if k ==0or k > n:
        print("null")
        return
    
    car_x = int(input[ptr])
    ptr +=1
    car_y = int(input[ptr])
    ptr +=1
    
    chargers = []
    for i in range(n):
        x = int(input[ptr])
        ptr +=1
        y = int(input[ptr])
        ptr +=1
        distance = abs(car_x - x) + abs(car_y - y)
        chargers.append( (distance, i+1, x, y) )  # i+1是编号
    
    # 按距离升序,距离相同按编号升序
    chargers.sort(key=lambda x: (x[0], x[1]))
    
    for i in range(k):
        d, idx, x, y = chargers[i]
        print(f"{idx} {x} {y} {d}")

if __name__ == "__main__":
    main()

第二题:建设基站

有一棵二叉树,每个节点上都住了一户居民。现在要给这棵树上的居民建设基站,每个基站只能覆盖她所在与相邻的节点,请问信号覆盖这棵树最少需要建设多少个基站

输入描述

一个整数数组 nums(1<=num.length<=3000),用空格分隔,表示二叉树的节点值,正整数表示存在节点,N 表示不存在节点,如[1 2 3 4 N 5 6]表示一颗如下所示的树,最少需要建设2个基站

输出描述

最少需要建设的基站个数

样例输入

1 2 3 4 N 5 6

样例输出

2

参考题解

树形dp,步骤如下:构建二叉树:根据输入的层序遍历数组构建二叉树结构。递归处理节点:使用深度优先搜索(DFS)递归处理每个节点,计算其三种状态的最小基站数目。状态转移:状态0:当前节点放置基站,覆盖自身及其子节点。状态1:当前节点未被覆盖,需要父节点覆盖,子节点必须被覆盖。状态2:当前节点被覆盖,未放置基站,覆盖来自子节点。结果计算:根节点的最终结果为状态0和状态2的最小值,确保整棵树被覆盖。

C++:

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <climits>
#include <algorithm>
using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

TreeNode* buildTree(const vector<string>& nums) {
    if (nums.empty()) return nullptr;
    TreeNode* root = new TreeNode(stoi(nums[0]));
    queue<TreeNode*> q;
    q.push(root);
    int i = 1;
    while (!q.empty() && i < nums.size()) {
        TreeNode* node = q.front(); q.pop();
        if (nums[i] != "N") {
            node->left = new TreeNode(stoi(nums[i]));
            q.push(node->left);
        }
        i++;
        if (i < nums.size() && nums[i] != "N") {
            node->right = new TreeNode(stoi(nums[i]));
            q.push(node->right);
        }
        i++;
    }
    return root;
}

int minStationCover(const vector<string>& nums) {
    const int INF = INT_MAX;

    function<tuple<int, int, int>(TreeNode*)> dfs = [&](TreeNode* node) {
        if (!node) return make_tuple(INF, INF, 0);
        auto [l0, l1, l2] = dfs(node->left);
        auto [r0, r1, r2] = dfs(node->right);

        // 状态0: 当前节点放置基站
        int minL0 = min({l0, l1, l2});
        int minR0 = min({r0, r1, r2});
        int dp0 = 1 + minL0 + minR0;

        // 状态1: 当前节点未被覆盖,父节点必须覆盖
        int dp1 = l2 + r2;

        // 状态2: 当前节点被覆盖,未放置基站,覆盖来自子节点
        int option1 = l0 + min(r0, r2);
        int option2 = r0 + min(l0, l2);
        int option3 = l0 + r0;
        int dp2 = min({option1, option2, option3});

        return make_tuple(dp0, dp1, dp2);
    };

    TreeNode* root = buildTree(nums);
    if (!root) return 0;
    auto [dp0, dp1, dp2] = dfs(root);
    return min(dp0, dp2);
}

int main() {
    vector<string> nums;
    string token;
    while (cin >> token) {
        nums.push_back(token);
    }
    cout << minStationCover(nums) << endl;
    return 0;
}

Java:

import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class Solution {
    public static TreeNode buildTree(String[] nums) {
        if (nums.length == 0) return null;
        TreeNode root = new TreeNode(Integer.parseInt(nums[0]));
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        int i = 1;
        while (!q.isEmpty() && i < nums.length) {
            TreeNode node = q.poll();
            if (!nums[i].equals("N")) {
                node.left = new TreeNode(Integer.parseInt(nums[i]));
                q.add(node.left);
            }
            i++;
            if (i < nums.length && !n

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

和尚也是&nbsp;20&nbsp;年毕业的牛友了,当年秋招也是一把活跃好手。从毕业到现在,一直都是整租一套房子,然后自己选择室友,刚开始是大学朋友,再然后是校招认识的人合租。自己整租房子,最大的好处就是,不会把室友变成陌生人,也有一定的信任感。这里也给自己找【出租+找室友】!!##&nbsp;出租房间信息●&nbsp;房地点:北京昌平区回龙观龙泽龙华园二区,南北通透●&nbsp;出租卧室:朝北次卧,15&nbsp;平房间●入住时间:随时入住,随时看房 ●&nbsp;整体房间:110&nbsp;平,正规&nbsp;3&nbsp;室,3&nbsp;室&nbsp;1&nbsp;厅,&nbsp;1&nbsp;卫&nbsp;1&nbsp;厨●&nbsp;公共区域:客厅&nbsp;28&nbsp;平、卫生间(厕所/洗漱台是分开的)、厨房也很棒●&nbsp;价格:房租&nbsp;2400&nbsp;元/月&nbsp;(押一付三)(无中介费!!无中介费!!)●&nbsp;物业+集体供暖费全包##&nbsp;小区周边和地铁●&nbsp;地铁方便:距离龙泽地铁站,公交车&nbsp;5&nbsp;分钟、步行&nbsp;900+&nbsp;米,通勤幸福指数拉满●&nbsp;小区对面就是华联购物中心、超市、小吃街等●&nbsp;距离滴滴的天空之城职场&nbsp;2&nbsp;公里(骑车几分钟到)●&nbsp;距离西二旗、软件园、百度、腾讯、网易、微博、小米、快手等等都不远##&nbsp;室友要求和现有室友●&nbsp;要求男、不抽烟、友好和谐相处●&nbsp;滴滴程序猿男(我)+滴滴运营男(另外一个人),很好相处●&nbsp;不接受情侣合租,可接受周末对象来****************,备注牛客租房
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务