【华为笔试题汇总】[华为机试经验贴分享] 2023-08-23-华为秋招笔试题

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员

✨ 本系列打算持续跟新华为近期的春秋招笔试题汇总~

💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导

👏 感谢大家的订阅➕ 和 喜欢💗

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新。

💻 前言

🍭 关于华为

  • 据说今晚有华为的机试啦,华为的春招也算是正式开始了,关于华为的笔试,大家可以自由选时间去安排,大致时间就是每周三,具体哪一周需要自己去做决定,和 HR 沟通或者邮件📧反馈,一般会有 HR 联系你修改信息,包括后面笔试的成绩,也可以问 HR ,华为的 HR 是真滴很不错 👍

📓 笔试要求

  • 华为的笔试有个硬性规定,笔试分是需要达到 150/600 分才算是通过,三道题目的构成分数构成为 100200300 分,后续的面试流程会根据笔试成绩来进行排序哦。

🪜 笔试技巧

笔试的思维破局

  • 之前写别的公司机试的小伙伴一般都是按照顺序来写的,因为越往后的题目难度越高,这样会形成一个惯性,做每家公司的笔试都这么干。
  • 但华为题目的代码编写难易度并不一定是递进的,比如第一题可能是题意很简单,但是码量很大。第三题 可能代码随便写几行就能拿到很多分,大家在机试的时候需要把把握好做题的顺序,每道题可以都先过一遍。

骗分技巧

  • 适当使用暴力骗分,如果对于当前这题没有什么想法,不要多想直接写暴力或许能拿到不少的分数。
  • 对于题目要求输出 Yes or No ,或者无解输出 -1 的情况,那么可以试试直接输出,一般也能拿到一些分数
  • 这里捞一点那里骗一点,说不定就够 150 分了哦

🥰 题目练手

那么本次就给大家带来去年秋招的华为的真题练练手,祝大家今晚发挥超长,笔试 AK !! !!

_________________________________________

✈️ 笔试题目

🍋 01.网络连通性分析

问题描述

K小姐是一名网络工程师,她搭建了一个复杂的网络系统。在这个网络系统中,一共有 N N N 个节点,每个节点都有一个独一无二的标识,我们称之为节点名。每个节点拥有 t t t 个端口,这些端口用于节点之间的报文传输。为了管理网络,K小姐将所有端口分配了一个连通块编号(用 id 表示)。

连通性规则如下:

  1. 若两个端口的 id 相同,则它们属于同一个连通块,这两个端口是连通的。
  2. 若两个端口的 id 不同,则它们不连通。

现在,K小姐想要知道,哪些节点与特定的节点 A 是连通的,即通过至少一个端口与节点 A 属于同一个连通块。

输入格式

第一行包含一个整数 m m m m m m 个整数,代表节点 A 的端口数量以及每个端口的 id。

第二行包含一个整数 n n n,代表除节点 A 之外网络中的其他节点数量。

接下来的 n n n 行,每行的格式为: N a m e   t   i d 1   i d 2   . . .   i d t Name\ t\ id_1\ id_2\ ...\ id_t Name t id1 id2 ... idt

输出格式

第一行输出一个整数 N N N,代表与节点 A 连通的节点的总数。

第二行输出 N N N 个整数,按照节点的 N a m e Name Name 从小到大排序。

样例输入

2 1 2
4
1000 3 4 3 5
1001 2 1 2
114514 3 1 2 3
1919810 1 1

样例输出

3
1001 114514 1919810

数据范围

  • 0 ≤ n ≤ 4000 0 \le n \le 4000 0n4000
  • 1 ≤ N a m e ≤ 4294967294 1 \le Name \le 4294967294 1Name4294967294

题解

要解决这个问题,我们需要创建一个集合来存储节点 A 的所有端口 id。然后,遍历每个其他节点的端口,如果某个端口的 id 在节点 A 的端口 id 集合中,那么这个节点就与节点 A 连通。我们将所有连通的节点收集起来并排序输出。

参考代码

  • Python
n, *a_ids = map(int, input().split())
count = int(input())
connected_nodes = []

for _ in range(count):
    name, t, *ids = map(int, input().split())
    if set(ids).intersection(a_ids):
        connected_nodes.append(name)

print(len(connected_nodes))
print(' '.join(map(str, sorted(connected_nodes))))
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        Set<Integer> setA = new HashSet<>();
        for (int i = 0; i < m; i++) {
            setA.add(scanner.nextInt());
        }

        int n = scanner.nextInt();
        List<Integer> connectedNodes = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int name = scanner.nextInt();
            int t = scanner.nextInt();
            boolean isConnected = false;
            for (int j = 0; j < t; j++) {
                if (setA.contains(scanner.nextInt())) {
                    isConnected = true;
                }
            }
            if (isConnected) {
                connectedNodes.add(name);
            }
        }
        Collections.sort(connectedNodes);
        
        System.out.println(connectedNodes.size());
        connectedNodes.forEach(name -> System.out.print(name + " "));
        System.out.println();
    }
}
  • Cpp
#include <iostream>
#include <unordered_set>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int m, n, id, name, t;
    cin >> m;
    unordered_set<int> aPorts;
    
    for (int i = 0; i < m; ++i) {
        cin >> id;
        aPorts.insert(id);
    }

    cin >> n;
    vector<unsigned int> connectedNodes;

    for (int i = 0; i < n; ++i) {
        bool isConnected = false;
        cin >> name >> t;
        for (int j = 0; j < t; ++j) {
            cin >> id;
            if (aPorts.find(id) != aPorts.end()) {
                isConnected = true;
            }
        }
        if (isConnected) {
            connectedNodes.push_back(name);
        }
    }

    sort(connectedNodes.begin(), connectedNodes.end());

    cout << connectedNodes.size() << endl;
    for (const auto &node : connectedNodes) {
        cout << node << " ";
    }
    cout << endl;

    return 0;
}

🍎 02.K小姐的文本编辑器

题目描述

K小姐最近在开发一款文本编辑器,她希望这个编辑器能够实现一些基本的文本操作功能。这款编辑器需要支持以下操作:

  1. insert str:在当前光标位置插入字符串 s t r str str,并将光标移动到插入的字符串的末尾。
  2. delete len:删除光标左侧长度为 l e n len len 的字符串。如果 l e n < 0 len \lt 0 len<0 或者 l e n len len 大于光标左侧的字符串长度,则不进行操作。
  3. move cnt:将光标移动 c n t cnt cnt 个位置。如果 c n t cnt cnt 为负数,则向左移动;如果 c n t cnt cnt 为正数,则向右移动。如果 c n t cnt cnt 超出字符串的边界,则不进行移动。
  4. copy:将光标左侧的字符串复制并插入到光标的右侧,光标位置保持不变。

现在,K小姐已经完成了这款文本编辑器的开发,你正在进行测试。给定一系列操作命令,请你输出执行这些操作后得到的最终文本内容。

输入格式

输入由多行组成,每行包含一个操作命令。操作命令的格式如题目描述所示。
输入以 end 结束,表示操作结束。
初始时,文本内容为空,光标位置为 0 0 0

输出格式

输出执行所有操作后得到的最终文本内容。
请用 | 表示光标的位置。

样例输入

insert test
insert pass
move 10
delete 4
insert fail
move -4
copy
end

样例输出

test|testfail

数据范围

  • 1 ≤ s t r . l e n g t h ≤ 40 1 \le str.length \le 40 1str.length40
  • 1 ≤ l e n ≤ 40 1 \le len \le 40 1len40
  • − 40 ≤ c n t ≤ 40 -40 \le cnt \le 40 40cnt40
  • insertdeletemovecopy 操作的总次数不超过 200 200 200 次。

题解

本题可以使用双端队列(deque)来模拟文本编辑器的操作。我们可以将光标左侧的字符存储在一个双端队列 front 中,将光标右侧的字符存储在另一个双端队列 back 中。

对于 insert 操作,我们将要插入的字符串压入 front 的尾部。

对于 delete 操作,我们从 front 的尾部弹出 l e n len len 个字符。

对于 move 操作,如果 c n t cnt cnt 为负数,我们将 front 尾部的字符弹出并压入 back 的头部,重复 − c n t -cnt cnt 次;如果 c n t cnt cnt 为正数,我们将 back 头部的字符弹出并压入 front 的尾部,重复 c n t cnt cnt 次。

对于 copy 操作,我们将 front 中的字符依次弹出并压入 back 的头部。

最后,我们将 frontback 中的字符拼接起来,并在中间插入 | 表示光标位置,即可得到最终的文本内容。

时间复杂度: O ( n ) O(n) O(n),其中 n n n 为操作的总次数。每个操作的时间复杂度为 O ( 1 ) O(1) O(1)
空间复杂度: O ( m ) O(m) O(m),其中 m m m 为最终文本内容的长度。

参考代码

  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Deque<Character> front = new ArrayDeque<>();
        Deque<Character> back = new ArrayDeque<>();
        
        while (sc.hasNext()) {
            String[] op = sc.nextLine().split(" ");
            if (op[0].equals("end")) {
                break;
            } else if (op[0].equals("insert")) {
                for (char c : op[1].toCharArray()) {
                    front.offerLast(c);
                }
            } else if (op[0].equals("delete")) {
                int len = Integer.parseInt(op[1]);
                while (len > 0 && len <= front.size()) {
                    front.pollLast();
                    len--;
                }
            } else if (op[0].equals("move")) {
                int cnt = Integer.parseInt(op[1]);
                while (cnt < 0 && -cnt <= front.size()) {
                    back.offerFirst(front.pollLast());
                    cnt++;
                }
                while (cnt > 0 && cnt <= back.size()) {
                    front.offerLast(back.pollFirst());
                    cnt--;
                }
            } else if (op[0].equals("copy")) {
                Deque<Character> temp = new ArrayDeque<>(front);
                while (!temp.isEmpty()) {
                    back.offerFirst(temp.pollLast());
                }
            }
        }
        
        StringBuilder sb = new StringBuilder();
        for (char c : front) {
            sb.append(c);
        }
        sb.append("|");
        for (char c : back) {
            sb.append(c);
        }
        System.out.println(sb.toString());
    }
}

🍌 03.K小姐的魔法镜阵

问题描述

K小姐收集了一些神奇的魔法镜,这些镜子可以吸收魔法光芒,并在一定时间后将光芒向四周散射。

这些魔法镜分为一级镜和二级镜两种类型。一级镜的散射速度较快,仅需 1 1 1 毫秒就能将光芒向上下左右四个方向散射;而二级镜则需要 2 2 2 毫秒才能完成散射。

K小姐将这些魔法镜按照整数坐标排列在一个二维矩阵中。现在,她在某个位置的魔法镜上施加了一道魔法光芒,想知道最早什么时候所有的魔法镜都能吸收到这道光芒。

注意:矩阵的下标从 0 0 0 开始。

输入格式

第一行包含两个正整数 n n n m m m,分别表示矩阵的列数和行数,满足 1 ≤ n , m ≤ 500 1 \le n,m \le 500 1n,m500

第二行包含两个正整数 i i i j j j,表示最初获得光芒的魔法镜的坐标。

接下来 m m m 行,每行包含 n n n 个整数,表示该位置魔法镜的等级:

  • 如果为 0 0 0,表示该位置是一堵密不透光的墙,它可以完全阻挡光芒的传播。
  • 如果为 1 1 1,表示该位置的魔法镜散射耗时 1 1 1 毫秒。
  • 如果为 2 2 2,表示该位置的魔法镜散射耗时 2 2 2 毫秒。

输出格式

输出一个整数,表示所有魔法镜都能吸收到光芒所需的最小时间。如果有些魔法镜无法吸收到光芒,则输出 − 1 -1 1

样例输入

5
5
2 2
1 0 2 1 0
2 2 1 2 0
0 0 1 0 0
2 1 1 0 0
1 1 1 1 1

样例输出

6

数据范围

1 ≤ n , m ≤ 500 1 \le n,m \le 500 1n,m500
0 ≤ i < m 0 \le i < m 0i<m
0 ≤ j < n 0 \le j < n 0j<n

题解

本题可以使用最短路算法(如Dijkstra算法)来求解。

我们可以将每个位置看作图中的一个节点,如果两个相邻位置间没有墙阻隔,则它们之间存在一条边,边的权重为该位置魔法镜的散射时间。

然后,从起始位置开始,使用Dijkstra算法计算到达每个位置的最短时间。在算法过程中,我们可以记录下最长的最短时间,即为所有魔法镜都吸收到光芒所需的最小时间。

如果在算法结束后,仍有位置的最短时间为无穷大,说明该位置无法被光芒照射到,此时输出 − 1 -1 1

算法的时间复杂度为 O ( n m log ⁡ n m ) O(nm \log nm) O(nmlognm),空间复杂度为 O ( n m ) O(nm) O(nm)

参考代码

  • Python
import heapq

n = int(input())
m = int(input())
start_x, start_y = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(m)]
dist = [[10 ** 9] * n for _ in range(m)]
visited = [[False] * n for _ in range(m)]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

dist[start_x][start_y] = 0
pq = [(0, start_x, start_y)]

while pq:
    d, x, y = heapq.heappop(pq)
    if visited[x][y]:
        continue
    visited[x][y] = True
    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]
        if 0 <= nx < m and 0 <= ny < n and matrix[nx][ny] != 0:
            new_dist = d + matrix[x][y]
            if new_dist < dist[nx][ny]:
                dist[nx][ny] = new_dist
                heapq.heappush(pq, (new_dist, nx, ny))

ans = 0
for i in range(m):
    for j in range(n):
        if matrix[i][j] != 0:
            ans = max(ans, dist[i][j])

print(ans if ans != 10 ** 9 else -1)

🍍 写在最后

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新。

在这里插入图片描述

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值