2025华为暑期机试题目记录

2025华为暑期机试题目100+200+300*20%

第一题 补丁版本

某测试工具升级时总选择迭代次数最多的补丁版本,已知这些补丁版本的前序版本(即依赖该版本修改发布新补丁版本),前序版本的个数<=1,且不会存在互为前序版本的情况。请给出最终可以升级的补丁版本。版本号只包含大写字母和数字。
输入:第一行为记录的版本迭代关系个数N,范围是[1,100000];第二行到第N+1行:每行包含两个字符串,第一个字符串为当前版本,第二个字符串为前序版本,用空格隔开。字符串包含字符个数为[1,100],没有前序版本的第二个字符串固定为NA。

6
CN0010 BF0001
BF0001 AZ0001
AZ0001 NA
BF0010 AZ0001
AW0001 NA
BF0011 AZ0001

输出

CN0010

具体代码

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

int main() {
    int n;
    cin >> n;

    unordered_map<string, vector<string>> graph; // 前序 -> 当前
    unordered_map<string, int> in_degree;         // 入度
    unordered_map<string, int> depth;             // 版本的迭代次数
    unordered_map<string, bool> exist;            // 所有出现过的版本

    for (int i = 0; i < n; ++i) {
        string cur, pre;
        cin >> cur >> pre;
        exist[cur] = true;
        if (pre != "NA") {
            graph[pre].push_back(cur);
            in_degree[cur]++;
            exist[pre] = true;
        } else {
            // 确保NA情况也初始化
            if (!in_degree.count(cur)) in_degree[cur] = 0;
        }
    }

    // 拓扑排序
    queue<string> q;
    for (auto &p : exist) {
        if (in_degree[p.first] == 0) {
            q.push(p.first);
            depth[p.first] = 0; // 根节点迭代次数为0
        }
    }

    while (!q.empty()) {
        string node = q.front();
        q.pop();

        for (string &next : graph[node]) {
            depth[next] = max(depth[next], depth[node] + 1);
            in_degree[next]--;
            if (in_degree[next] == 0) {
                q.push(next);
            }
        }
    }

    // 找最大深度
    int max_depth = 0;
    for (auto &p : depth) {
        max_depth = max(max_depth, p.second);
    }

    // 收集所有最大深度版本
    vector<string> result;
    for (auto &p : depth) {
        if (p.second == max_depth) {
            result.push_back(p.first);
        }
    }

    sort(result.begin(), result.end());
    for (int i = 0; i < result.size(); ++i) {
        if (i > 0) cout << " ";
        cout << result[i];
    }
    cout << endl;

    return 0;
}

解决思路:
处理输入构建图,处理每条路的依赖关系。然后用拓扑排序计算深度,将所有入度为0的节点加入队列,取出节点在遍历其后继节点,然后更新后继的深度为当前节点深度+1与已有最大值深度的较高者。减少后继的入度,假如为0就加入队列。最后遍历所有版本,找到最大值,根据最大值找到其对应版本。排序后输出。

第二题 地铁耗时最短的线路

大湾区某城市地铁线路非常密集,乘客很难一眼看出选择哪条线路乘型比较合适,为了解决这个问题,地铁公司希望你开发一个程序帮助乘客挑选合适的乘坐线路,使得乘坐时间最短,地铁公司可以提供的数据是各相邻站点之间的乘坐时间。
输入
第一行:N,站点总数,3<=N<=20.第二行:乘客的出发和到达站点。第三行起:相邻站点之间的乘坐时间,每对站点一行,站点名称是单个小写字母,站点名一定包括出发和到达站点,输入保证只有一个唯一解;结束行:0000

12
a e
a b 2
b c 2
c d 2
d e 2
f b 3
b g 3
g h 2
h i 3
j h 2 
h e 3
e k 2
k l 4
0000

输出

a b c d e

blog.csdnimg.cn/direct/4e2e0b5862514d44be632034a7bc9fa2.jpeg)
具体代码

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

struct Edge {
    string to;
    int time;
};

int main() {
    int N;
    cin >> N;

    string start, end;
    cin >> start >> end;

    unordered_map<string, vector<Edge>> graph;
    string u, v;
    int t;

    while (cin >> u) {
        if (u == "0000") break;
        cin >> v >> t;
        graph[u].push_back({v, t});
        graph[v].push_back({u, t});  // 双向图
    }

    // Dijkstra
    unordered_map<string, int> dist;
    unordered_map<string, string> prev;
    for (auto &p : graph) {
        dist[p.first] = INT_MAX;
    }
    dist[start] = 0;

    auto cmp = [&](const pair<int, string>& a, const pair<int, string>& b) {
        return a.first > b.first;
    };
    priority_queue<pair<int, string>, vector<pair<int, string>>, decltype(cmp)> pq(cmp);
    pq.push({0, start});

    while (!pq.empty()) {
        auto [d, cur] = pq.top(); pq.pop();

        if (d > dist[cur]) continue;

        for (auto &edge : graph[cur]) {
            int new_dist = d + edge.time;
            if (new_dist < dist[edge.to]) {
                dist[edge.to] = new_dist;
                prev[edge.to] = cur;
                pq.push({new_dist, edge.to});
            }
        }
    }

    // 输出路径
    vector<string> path;
    string curr = end;
    while (curr != start) {
        path.push_back(curr);
        curr = prev[curr];
    }
    path.push_back(start);
    reverse(path.begin(), path.end());

    for (int i = 0; i < path.size(); ++i) {
        if (i > 0) cout << " ";
        cout << path[i];
    }
    cout << endl;

    return 0;
}

解决思路:
首先根据输入读取节点站和每条边的权重来构建无向图,再使用迪杰斯特拉算法求最短路径,最后再由终点回溯回起点,反转结果再输出。
迪杰斯特拉算法具体实现过程:首先初始化所有距离为无穷大,初始距离为0,在利用优先队列构建最小堆,初始节点入队。进入主循环,获取当前距离最小节点,如果已经处理过就跳过,遍历所有邻接边,更新距离再入队。

第三题 最小操作次数

给定一个的二维矩阵NN,其中包含[1,N^2]的互不相同的正整数。定义一种操作:每次可以选择矩阵中的一个元素,将其与其在顺时针螺旋顺序中的下一个元素交换位置例如: 在33的矩阵中,螺旋顺序为从左上角[0,0]开始,向右到[0,2],向下到[2,2],向左到[2,0],再向上到[1,0],最后到中心[1,1]。目标是通过若干次操作,将矩阵变为“顺时针螺旋递增”顺序,即螺旋遍历时元素依次为1,2,3,4…N^2。求将给定矩阵转换为顺时针螺旋递增顺序所需的最小操作次数。
输入

2
3 1
2 4

输出

3

具体代码

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
const int MOD = 1e9 + 7;

// 螺旋顺序展开
vector<int> spiralOrder(const vector<vector<int>>& matrix, int N) {
    vector<int> spiral;
    int top = 0, bottom = N - 1, left = 0, right = N - 1;
    while (top <= bottom && left <= right) {
        for (int j = left; j <= right; j++) spiral.push_back(matrix[top][j]);
        top++;
        for (int i = top; i <= bottom; i++) spiral.push_back(matrix[i][right]);
        right--;
        if (top <= bottom)
            for (int j = right; j >= left; j--) spiral.push_back(matrix[bottom][j]);
        bottom--;
        if (left <= right)
            for (int i = bottom; i >= top; i--) spiral.push_back(matrix[i][left]);
        left++;
    }
    return spiral;
}

// 求最小交换次数(基于置换环)
int minSpiralSwaps(const vector<int>& spiral) {
    int n = spiral.size();
    // 构造 target 值到索引的映射(目标是1~n递增)
    vector<int> pos(n);  // pos[i] 表示 spiral[i] 在目标数组中应该在的位置
    for (int i = 0; i < n; ++i) {
        pos[i] = spiral[i] - 1; // 值为1~n,对应目标下标0~n-1
    }

    vector<bool> visited(n, false);
    long long swaps = 0;
    for (int i = 0; i < n; ++i) {
        if (visited[i] || pos[i] == i)
            continue;
        int cycle_len = 0;
        int j = i;
        while (!visited[j]) {
            visited[j] = true;
            j = pos[j];
            cycle_len++;
        }
        swaps = (swaps + cycle_len - 1) % MOD;
    }
    return swaps;
}

int main() {
    int N;
    cin >> N;
    vector<vector<int>> matrix(N, vector<int>(N));
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            cin >> matrix[i][j];

    vector<int> spiral = spiralOrder(matrix, N);
    int result = minSpiralSwaps(spiral);
    cout << result << endl;
    return 0;
}

解决思路:
首先螺旋展开数组,再利用置换环计算交换次数。

### 华为OD机考题概述 华为OD作为企业招聘的重要环节之一,其题设计通常涵盖了多种编程语言和技术领域。对于2025年的华为OD题,虽然具体的题目尚未完全公开,但可以通过已有的资料推测出一些常见的考察方向和知识点。 #### 编程语言支持 根据已有信息[^1],华为OD支持多种编程语言,包括但不限于Java、Python、C++以及JavaScript等。这些语言的选择不仅反映了技术的多样性,也体现了对不同岗位技能需求的关注。 #### 常见考点分析 以下是基于过往经验总结的一些常见考点: 1. **数据结构与算法** 数据结构方面可能涉及数组、链表、堆栈、队列、树形结构等内容;而算法则会测排序、查找、动态规划等方面的知识点[^2]。 2. **字符串处理** 字符串操作是另一大重点,比如模式匹配、子串提取、字符替换等问题都是高频出现的内容。 3. **多线程与并发控制** 对于高级职位而言,可能会涉及到更复杂的概念如锁制、信号量使用等并行计算相关内容。 4. **数据库基础** SQL查询语句编写也是不可忽视的一部分,尤其是针对复杂关系型数据库的操作能力评估。 ```java // Java示例代码:实现简单的冒泡排序算法 public class BubbleSort { public static void main(String[] args) { int[] array = {6, 8, 3, 9, 7}; bubbleSort(array); System.out.println(Arrays.toString(array)); } private static void bubbleSort(int[] arr){ boolean swapped; do{ swapped=false; for (int i=0;i<arr.length-1;i++) { if (arr[i]>arr[i+1]){ swap(arr,i,i+1); swapped=true; } } }while(swapped); } private static void swap(int[] a,int i ,int j ){ int temp=a[i]; a[i]=a[j]; a[j]=temp; } } ``` 上述代码展示了如何利用Java来完成基本的冒泡排序功能。 #### 在线练习资源推荐 为了更好地准备此类考,可以访问指定的在线OJ平台进行模拟训练。通过不断实践真实场景下的编码挑战,能够有效提升解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值