华为笔试 华为软开 华为秋招 0910
笔试时间:2025年9月10日
往年笔试合集:
第一题
给定一个迷宫的地图,地图是一个二维矩阵,其中 0
表示通道,1
表示墙壁,S
表示起点,E
表示终点。需要从起点 S
出发,通过最短路径到达终点 E
,返回最短路径的步数。如果无法到达终点,返回 -1
。迷宫中会有虫洞,用数字 2
表示,若走入虫洞可以穿越到另一个虫洞出口,不耗费步数。只能上下左右移动,且不能走出迷宫的边界,也不能穿越墙壁。
输入描述
第一行包含两个整数 m n
(1 ≤ m, n ≤ 1000
),表示迷宫的行数和列数。接下来的 m
行,每行包含 n
个字符,表示迷宫的地图。
输出描述
如果能够到达终点,输出最短路径的步数。如果无法到达终点,输出 -1
。
样例输入
5 5
S0000
11110
01100
01010
0000E
样例输出
8
参考题解
解题思路: 这是一个带传送门的迷宫最短路径问题,使用BFS(广度优先搜索)解决。关键点是虫洞传送不消耗步数,需要使用双端队列,虫洞传送使用appendleft
加入队列头部,确保步数少的节点先被扩展。
C++:
#include <iostream> #include <vector> #include <deque> #include <map> #include <string> using namespace std; int main() { int m, n; cin >> m >> n; vector<string> maze(m); pair<int, int> st, ed; vector<pair<int, int>> holes; for (int i = 0; i < m; i++) { cin >> maze[i]; for (int j = 0; j < n; j++) { if (maze[i][j] == 'S') { st = {i, j}; } else if (maze[i][j] == 'E') { ed = {i, j}; } else if (maze[i][j] == '2') { holes.push_back({i, j}); } } } map<pair<int, int>, pair<int, int>> hole_map; if (holes.size() == 2) { hole_map[holes[0]] = holes[1]; hole_map[holes[1]] = holes[0]; } deque<tuple<int, int, int>> q; q.push_back({st.first, st.second, 0}); vector<vector<bool>> visited(m, vector<bool>(n, false)); visited[st.first][st.second] = true; int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; while (!q.empty()) { auto [x, y, step] = q.front(); q.pop_front(); if (make_pair(x, y) == ed) { cout << step << endl; return 0; } if (hole_map.count({x, y})) { auto [nx, ny] = hole_map[{x, y}]; if (!visited[nx][ny]) { visited[nx][ny] = true; q.push_front({nx, ny, step}); } } for (auto& dir : dirs) { int nx = x + dir[0]; int ny = y + dir[1]; if (nx >= 0 && nx < m && ny >= 0 && ny < n) { if (maze[nx][ny] != '1' && !visited[nx][ny]) { visited[nx][ny] = true; q.push_back({nx, ny, step + 1}); } } } } cout << -1 << endl; return 0; }
Java:
import java.util.*; public class Solution { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int m = sc.nextInt(); int n = sc.nextInt(); sc.nextLine(); String[] maze = new String[m]; int[] st = new int[2]; int[] ed = new int[2]; List<int[]> holes = new ArrayList<>(); for (int i = 0; i < m; i++) { maze[i] = sc.nextLine(); for (int j = 0; j < n; j++) { if (maze[i].charAt(j) == 'S') { st = new int[]{i, j}; } else if (maze[i].charAt(j) == 'E') { ed = new int[]{i, j}; } else if (maze[i].charAt(j) == '2') { holes.add(new int[]{i, j}); } } } Map<String, int[]> holeMap = new HashMap<>(); if (holes.size() == 2) { String key1 = holes.get(0)[0] + "," + holes.get(0)[1]; String key2 = holes.get(1)[0] + "," + holes.get(1)[1]; holeMap.put(key1, holes.get(1)); holeMap.put(key2, holes.get(0)); } Deque<int[]> q = new LinkedList<>(); q.offer(new int[]{st[0], st[1], 0}); boolean[][] visited = new boolean[m][n]; visited[st[0]][st[1]] = true; int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; while (!q.isEmpty()) { int[] curr = q.poll(); int x = curr[0], y = curr[1], step = curr[2]; if (x == ed[0] && y == ed[1]) { System.out.println(step); return; } String key = x + "," + y; if (holeMap.containsKey(key)) { int[] next = holeMap.get(key); if (!visited[next[0]][next[1]]) { visited[next[0]][next[1]] = true; q.offerFirst(new int[]{next[0], next[1], step}); } } for (int[] dir : dirs) { int nx = x + dir[0]; int ny = y + dir[1]; if (nx >= 0 && nx < m && ny >= 0 && ny < n) { if (maze[nx].charAt(ny) != '1' && !visited[nx][ny]) { visited[nx][ny] = true; q.offer(new int[]{nx, ny, step + 1}); } } } } System.out.println(-1); } }
Python:
from collections import deque def solve(): m, n = map(int, input().split()) maze = [list(input().strip()) for _ in range(m)] st, ed = None, None holes = [] for i in range(m): for j in range(n): if maze[i][j] == 'S': st = (i, j) elif maze[i][j] == 'E': ed = (i, j) elif maze[i][j] == '2': holes.append((i, j)) hole_map = {} if len(holes) == 2: a, b = holes hole_map[a] = b hole_map[b] = a q = deque() q.append((st[0], st[1], 0)) visited = [[False] * n for _ in range(m)] visited[st[0]][st[1]] = True dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] while q: x, y, step = q.popleft() if (x, y) == ed: print(step) return if (x, y) in hole_map: nx, ny = hole_map[(x, y)] if not visited[nx][ny]: visited[nx][ny] = True q.appendleft((nx, ny, step)) for dx, dy in dirs: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n: if maze[nx][ny] != '1' and not visited[nx][ny]: visited[nx][ny] = True q.append((nx, ny, step + 1)) print(-1) solve()
第二题
网络系统中VIP用户MAC地址配置格式为xx-xx-xx-xx-xx-xx/M,其中M标识MAC地址掩码长度。需要判断给定的MAC地址是否匹配VIP白名单中的任意一条规则。
输入描述
:输入第一行为整数 n
(1 ≤ n ≤ 100
),代表需要配置为VIP的MAC地址及其掩码个数。接下来 n
行是对应VIP用户MAC地址及其掩码长度,格式为xx-xx-xx-xx-xx-xx/M,其中 M
(0 ≤ M ≤ 48
)。然后是转发引擎等待处理的报文MAC地址数目 m
(1 ≤ m ≤ 100
)。接下来 m
行是转发引擎等待处理的报文MAC地址。
输出描述
输出 m
个转发引擎等待处理的报文MAC地址是否可以优先调度,是输出YES,不是则输出NO。
样例输入
2
00-d8-61-ef-31-3e/48
00-e0-fc-00-ed-50/40
2
00-e0-fc-00-ed-66
00-d8-61-ef-31-3f
样例输出
YES
NO
参考题解
解题思路:将MAC地址字符串转换为48位整数,便于进行位运算。对于每条VIP规则,通过右移操作比较前M位是否匹配。
C++:
#include <iostream> #include <string> #include <vector> #include <sstream> using namespace std; long long parseMac(string s) { s.erase(remove(s.begin(), s.end(), '-'), s.end()); return stoll(s, nullptr, 16); } int main() { int n; cin >> n; cin.ignore(); vector<pair<long long, int>> rules; for (int i = 0; i < n; i++) { string line; getline(cin, line); int pos = line.find('/'); string macStr = line.substr(0, pos); int maskLen = stoi(line.substr(pos + 1)); rules.push_back({parseMac(macStr), maskLen}); } int m; cin >> m; cin.ignore(); for (int i = 0; i < m; i++) { string mac; getline(cin, mac); if (mac.empty()) continue; long long p = parseMac(mac); bool isMatch = false; for (auto& rule : rules) { long long vip = rule.first; int mask = rule.second; int shift = 48 - mask; if ((p >> shift) == (vip >> shift)) { isMatch = true; break; } } cout << (isMatch ? "YES" : "NO") << endl; } return 0; }
Java:
import java.util.*; public class Solution { public static long parseMac(String s) { s = s.replace("-", ""); return Long.parseLong(s, 16); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine(); List<long[]> rules = new ArrayList<>(); for (int i = 0; i < n; i++) { String line = sc.nextLine(); String[] parts = line.split("/"); long mac = parseMac(parts[0]); int maskLen = Integer.parseInt(parts[1]); rules.add(new long[]{mac, maskLen}); } int m = sc.nextInt(); sc.nextLine(); for (int i = 0; i < m; i++) { String mac = sc.nextLine(); if (mac.isEmpty()) continue; long p = parseMac(mac); boolean isMatch = false; for (long[] rule : rules) { long vip = rule[0]; int mask = (int)rule[1]; int shift = 48 - mask; if ((p >> shift) == (vip >> shift)) { isMatch = true; break; } } System.out.println(isMatch ? "YES" : "NO"); } } }
Python:
import sys def parse_mac(s): return int(s.replace('-', ''), 16) def process_data(): n = int(sys.stdin.readline()) rules = [] for _ in range(n): line = sys.stdin.readline().strip().split('/') mac_str, mask_len = line[0], int(line[1]) rules.append((parse_mac(mac_str), mask_len)) m = int(sys.stdin.readline()) for _ in range(m): mac = sys.stdin.readline().strip() if not mac: continue p = parse_mac(mac) is_match = False for vip, mask in rules: shift = 48 - mask if (p >> shift) == (vip >> shift): is_match = True break print("YES" if is_match else "NO") if __name__ == "__main__": process_data()
第三题
现有 N
个设备从左到右依次排列,需要寻找一条权重最大的最优连线策略,将这 N
个设备从左到右顺序连接起来。每个设备有多个端口,设备内部端口之间的连接叫内部连线,设备之间的端口连接叫外部连线。
输
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南