华为笔试 华为软开 华为秋招 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等多种语言做法集合指南

查看9道真题和解析