华为笔试 华为秋招 华为笔试题 0903

笔试时间:2025年9月3日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

本题定义的连通网络,是由有连接关系的一个或多个节点组成的无向图。连通网络中每个节点,都赋予了一个权重,表示该节点的重要程度;所有节点的权重的和,代表该连通网络的权重。假设一个连通网络中各个节点,权重都是唯一的,不会重复。请根据输入的节点和权重,以及节点的连接关系,分析输入包含的连通网络并计算连通网络对应的权重,最终输出权重最大的连通网络中权重最大的节点的名称,以及该网络整体的权重。

输入描述

第一行是节点数 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 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

10-02 19:29
已编辑
浙江科技大学 运营
点赞 评论 收藏
分享
迷茫的大四🐶:都收获五个了,兄弟那还说啥,不用改了,去玩吧
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务