华为笔试 华为秋招 华为笔试题 0903
笔试时间:2025年9月3日
往年笔试合集:
第一题
本题定义的连通网络,是由有连接关系的一个或多个节点组成的无向图。连通网络中每个节点,都赋予了一个权重,表示该节点的重要程度;所有节点的权重的和,代表该连通网络的权重。假设一个连通网络中各个节点,权重都是唯一的,不会重复。请根据输入的节点和权重,以及节点的连接关系,分析输入包含的连通网络并计算连通网络对应的权重,最终输出权重最大的连通网络中权重最大的节点的名称,以及该网络整体的权重。
输入描述
第一行是节点数 n,值的范围 [1, 160] 。
接下来会出现 n 行,每一行的第一个输入是节点的名称(长度小于等于32的字符串,只包含小写字母和数字),第二个是节点的权重,通过空格和节点名称分开,权重值的范围是[1, 10000] 。接着是节点连接关系的数量 ,值的范围 。接下来会出现 行,每一行包含两个节点的名称,表示有连接关系的两个节点,节点顺序不分先后,且节点名称均包含在上面的节点列表中。如果 ,代表节点间没有连接关系。
输出描述
找到权重最大的连通网络,输出权重最大的节点的名称,以及网络对应的权重(用例保证不同网络的权重不会相同)。
样例输入
1 node1 100 0
样例输出
node1 100
解释:以上输入,形成了一个连通网络,该连通网络只有一个节点 node1,所以权重最大的节点也是 node1,所有节点和是 ,所以输出 node1 100。
参考题解
建模节点和边每个节点有一个名字和一个权重。节点之间可能通过边连接。输入先给出节点和权重,再给出边的连接关系。划分连通网络连通网络本质上是无向图的连通分量。用深度优先搜索(DFS)或广度优先搜索(BFS)遍历未访问的节点,就能把整个连通分量找出来。计算连通网络权重和最大节点对于找到的每个连通分量,遍历其中的节点,累加权重,得到该网络的总权重;同时记录该分量中权重最大的节点。选择最终答案在所有连通分量中,找出权重和最大的分量。输出该分量中权重最大的节点的名字,以及分量总权重。
C++:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>
#include <stack>
using namespace std;
struct Node {
string name;
int weight;
};
void work() {
int n;
cin >> n;
unordered_map<string, int> mp;
vector<Node> nd(n);
for (int i = 0; i < n; i++) {
string s;
int w;
cin >> s >> w;
mp[s] = i;
nd[i] = {s, w};
}
vector<vector<int>> g(n);
string t;
cin >> t;
int m = 0;
if (!t.empty()) {
m = stoi(t);
}
for (int i = 0; i < m; i++) {
string a, b;
cin >> a >> b;
int x = mp[a];
int y = mp[b];
g[x].push_back(y);
g[y].push_back(x);
}
vector<int> vis(n, 0);
int ans = -1;
string nm = "";
for (int i = 0; i < n; i++) {
if (vis[i] == 0) {
stack<int> st;
st.push(i);
vis[i] = 1;
vector<int> comp;
while (!st.empty()) {
int u = st.top();
st.pop();
comp.push_back(u);
for (int v : g[u]) {
if (vis[v] == 0) {
vis[v] = 1;
st.push(v);
}
}
}
int sm = 0;
int mx = -1;
string nm2 = "";
for (int j : comp) {
int w = nd[j].weight;
sm += w;
if (w > mx) {
mx = w;
nm2 = nd[j].name;
}
}
if (sm > ans) {
ans = sm;
nm = nm2;
}
}
}
if (!nm.empty()) {
cout << nm << " " << ans << endl;
}
}
int main() {
work();
return 0;
}
Java:
import java.util.*;
import java.io.*;
public class Main {
static class Node {
String name;
int weight;
Node(String name, int weight) {
this.name = name;
this.weight = weight;
}
}
public static void work() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
Map<String, Integer> mp = new HashMap<>();
Node[] nd = new Node[n];
for (int i = 0; i < n; i++) {
String[] parts = br.readLine().split(" ");
String s = parts[0];
int w = Integer.parseInt(parts[1]);
mp.put(s, i);
nd[i] = new Node(s, w);
}
List<List<Integer>> g = new ArrayList<>();
for (int i = 0; i < n; i++) {
g.add(new ArrayList<>());
}
String t = br.readLine().trim();
int m = 0;
if (!t.isEmpty()) {
m = Integer.parseInt(t);
}
for (int i = 0; i < m; i++) {
String[] parts = br.readLine().split(" ");
String a = parts[0];
String b = parts[1];
int x = mp.get(a);
int y = mp.get(b);
g.get(x).add(y);
g.get(y).add(x);
}
int[] vis = new int[n];
int ans = -1;
String nm = "";
for (int i = 0; i < n; i++) {
if (vis[i] == 0) {
Stack<Integer> st = new Stack<>();
st.push(i);
vis[i] = 1;
List<Integer> comp = new ArrayList<>();
while (!st.isEmpty()) {
int u = st.pop();
comp.add(u);
for (int v : g.get(u)) {
if (vis[v] == 0) {
vis[v] = 1;
st.push(v);
}
}
}
int sm = 0;
int mx = -1;
String nm2 = "";
for (int j : comp) {
int w = nd[j].weight;
sm += w;
if (w > mx) {
mx = w;
nm2 = nd[j].name;
}
}
if (sm > ans) {
ans = sm;
nm = nm2;
}
}
}
if (!nm.isEmpty()) {
System.out.println(nm + " " + ans);
}
}
public static void main(String[] args) throws IOException {
work();
}
}
Python:
import sys
def work():
n = int(sys.stdin.readline())
mp = {}
nd = [{} for _ in range(n)]
for i in range(n):
s, w = sys.stdin.readline().split()
mp[s] = i
nd[i] = {"n": s, "w": int(w)}
g = [[] for _ in range(n)]
t = sys.stdin.readline().strip()
m = int(t) if t else 0
for _ in range(m):
a, b = sys.stdin.readline().split()
x, y = mp[a], mp[b]
g[x].append(y)
g[y].append(x)
vis = [0] * n
ans = -1
nm = ""
for i in range(n):
if vis[i] == 0:
st = [i]
vis[i] = 1
comp = []
while st:
u = st.pop()
comp.append(u)
for v in g[u]:
if vis[v] == 0:
vis[v] = 1
st.append(v)
sm = 0
mx = -1
nm2 = ""
for j in comp:
w = nd[j]["w"]
sm += w
if w > mx:
mx = w
nm2 = nd[j]["n"]
if sm > ans:
ans = sm
nm = nm2
if nm != "":
print(nm, ans)
if __name__ == "__main__":
work()
第二题
在数通设备进行配置下发时,可能会遇到需要下发一个或多个数据段的场景。例如在配置某协议支持的算法类型时,需要下发配置如 algorithm 1-10,15-20,用于表明支持的所有算法段范围为 1-10,15-20。为了简化用户操作,数据下发往往同时支持散列及段下发模式,同时对数据段的顺序不做要求,也允许 algorithm 1-9,10,17-20:15-15的方式。下发后的数据会整理合并保存在数据库中,合并结果满足以下条件:数据段无法继续合并。数据段从小到大排列。长度为 1 的数据段保存为单个数字形式。举例来说,algorithm 1-9,10,17-20:15-15下发后数据库中储存的数据为 1-10,15,17-20。
数据合并规则:在数据库已有数据的情况下,用户新下发的配置不会覆盖已有配置,而是将新增的数据段合并到已有数据中。 例如:数据库中已存在 1-10,15-20时,再下发 algorithm 5-11时,数据库数据会合并更新为 1-11,15-20。
数据删除规则:用户下发删除配置时,从已有范围中删除与下发范围重合的范围。 例如:数据库中已存在 1-10,15-20时,再下发 undo algorithm 5-11,16时,数据库会更新为 1-4,15,17-20。
任务:给定一系列配置/删除操作,输出最后的数据库更新结果。
输入描述
第一行为1个整数n,表示下发操作的数量,n ≤ 100。
接下来n行每行包含1个字符串,表明下发的配置/删除操作。
配置操作格式为 algorithm 数据,删除操作格式为 undo algorithm 数据。
数据格式描述:
1. 原子数据:单个正整数a,正整数区间a - b,其中a ≤ b,并且1 ≤ a,b ≤ 65536
2. 字符串数据由原子数据通过,连接组成,例如:a-b,c,d-e
注:
1. 用例保证所有输入均合法,输入不保证原子数据排序
2. 原子数据段的数量不超过100
3. 数据库中数据为空时,删除操作视为无效操作
输出描述
输出 1 个字符串,表明合并保存后的数据库结果。 数据格式与输入中描述的字符串数据格式相同。 若最终数据库为空,输出 0。
样例输入
3
undo algorithm 1-100
algorithm 1-10,15-20
undo algorithm 6,7,8,9-10
样例输出
1-5,15-20
解释:
数据库初始为空
配置 undo algorithm 1-100=> 无效,仍为空
配置 algorithm 1-10,15-20=> 1-10,15-20
配置 undo algorithm 6,7,8,9-10=> 1-5,15-20
参考题解
把任意输入的“散列/区间”统一表示为闭区间集合:单点记为区间 [a,a]。数据库始终维护为规范化后的区间序列,满足:
1. 互不相交;2) 有序;3) 相邻即合并([l₁,r₁]与 [l₂,r₂]若 l₂ ≤ r₁ + 1则合并为 [l₁,max(r₁,r₂)])。这一步等价于:按左端点排序后线性扫描做“并区间”。
- 增加(algorithm):把当前集合 S与新下发集合 T拼在一起,再做一次规范化。即 S ← norm(S ∪ T)。
- 删除(undo algorithm):计算区间差 S \ T。做法是对已规范化的 S,T做双指针线性扫描,逐段把 S中每个区间被 T切掉后的“剩余片段”加入答案:
- 若 q > o,先保留 [o, q − 1];
- 更新 o ← max(o, r + 1)(把被删除的部分右移到删除区间之后);
- 若此时 o > n,该段结束;
- 设当前保留段起点为 o,初值为该段左端 m;
- 依次处理所有与 [m,n]相交的删区间 [q,r] ∈ T:
- 扫完相交删区间后,若仍有 o ≤ n,保留 [o,n]。因 S,T已互不相交且有序,整个过程为线性时间,且产出天然仍互不相交、有序,无需再二次规范化。
按规范化序列输出:[l,r]输出为 l-r ,若 l = r输出为单点 l ;若最终为空输出 0 。
C++:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
vector<pair<int, int>> p(const string& s) {
vector<pair<int, int>> t;
stringstream ss(s);
string z;
while (getline(ss, z, ',')) {
// Trim whitespace
size_t start = z.find_first_not_of(" \t");
size_t end = z.find_last_not_of(" \t");
if (start == string::npos) continue;
z = z.substr(start, end - start + 1);
if (z.empty()) continue;
size_t pos = z.find('-');
int a, b;
if (pos != string::npos) {
a = stoi(z.substr(0, pos));
b = stoi(z.substr(pos + 1));
} else {
a = b = stoi(z);
}
t.push_back({a, b});
}
return t;
}
vector<pair<int, int>> g(vector<pair<int, int>> v) {
if (v.empty()) return {};
sort(v.begin(), v.end());
vector<pair<int, int>> u;
u.push_back(v[0]);
for (size_t i = 1; i < v.size(); i++) {
int d = v[i].first;
int e = v[i].second;
int& f = u.back().first;
int& h = u.back().second;
if (d <= h + 1) {
h = (e > h) ? e : h;
} else {
u.push_back({d, e});
}
}
return u;
}
vector<pair<int, int>> k(const vector<pair<int, int>>& x, vector<pair<int, int>> y) {
if (y.empty()) return x;
sort(y.begin(), y.end());
vector<pair<int, int>> z;
size_t a = 0, b = 0;
size_t lx = x.size(), ly = y.size();
while (a < lx) {
int m = x[a].first;
int n = x[a].second;
while (b < ly && y[b].second < m) b++;
int o = m;
while (b < ly && y[b].first <= n) {
int q = y[b].first;
int r = y[b].second;
if (r < o) {
b++;
continue;
}
if (q > o) {
z.push_back({o, q - 1});
}
o = (r + 1 > o) ? r + 1 : o;
if (o > n) break;
b++;
}
if (o <= n) {
z.push_back({o, n});
}
a++;
}
return z;
}
string f(const vector<pair<int, int>>& a) {
if (a.empty()) return "0";
vector<string> b;
for (const auto& p : a) {
if (p.first == p.second) {
b.push_back(to_string(p.first));
} else {
b.push_back(to_string(p.first) + "-" + to_string(p.second));
}
}
string result = b[0];
for (size_t i = 1; i < b.size(); i++) {
result += "," + b[i];
}
return result;
}
int main() {
int q;
cin >> q;
cin.ignore();
vector<string> l(q);
for (int i = 0; i < q; i++) {
getline(cin, l[i]);
}
vector<pair<int, int>> r;
for (const string& s : l) {
string trimmed = s;
size_t start = trimmed.find_first_not_of(" \t");
size_t end = trimmed.find_last_not_of(" \t");
if (start != string::npos) {
trimmed = trimmed.substr(start, end - start + 1);
}
string t;
int u = 0;
if (trimmed.substr(0, 15) == "undo algorithm ") {
if (r.empty()) continue;
t = trimmed.substr(15);
u = 0;
} else if (trimmed.substr(0, 10) == "algorithm ") {
t = trimmed.substr(10);
u = 1;
} else {
continue;
}
// Trim t
start = t.find_first_not_of(" \t");
end = t.find_last_not_of(" \t");
if (start != string::npos) {
t = t.substr(start, end - start + 1);
}
if (t.empty()) continue;
vector<pair<int, int>> v = p(t);
if (u == 1) {
vector<pair<int, int>> combined = r;
combined.insert(combined.end(), v.begin(), v.end());
r = g(combined);
} else {
r = k(r, g(v));
}
}
cout << f(r) << endl;
return 0;
}
Java:
import java.util.*;
import java.io.*;
public class Main {
static List<int[]> p(String s) {
List<int[]> t = new ArrayList<>();
String[] parts = s.split(",");
for (String z : parts) {
z = z.trim();
if (z.isEmpty()) continue;
int a, b;
if (z.contains("-")) {
String[] nums = z.split("-");
a = Integer.parseInt(nums[0]);
b = Integer.parseInt(nums[1]);
} else {
a = b = Integer.parseInt(z);
}
t.add(new int[
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
查看10道真题和解析