华为笔试 华为秋招 华为笔试题 0924

笔试时间:2025年9月24日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:海蒂爷爷的木桶

海蒂爷爷想做一个奇怪的木桶。

他去山里砍了一些木柴并加工成高矮不一的木板,然后他把木板按高矮排好顺序,依次取出,竖在地上,排列成一个圆桶状。该圆桶满足循环单调非递减规律(即从第1块木板开始,后续的木板不矮于前一根,直到最高的木板与第一块最矮的木板连接在一起)。

比如序列 3 4 5 1 2 1,表示有7根木板,最矮的木板高度为1,最高的木板高度为5。起始木板高度为3,然后按木板高度依次排列,直到排到最高木板后,再从高度为1的最矮木板开始继续排列。

正当海蒂爷爷想用铁箍将木桶箍上时,小海蒂从远处跑来,递给爷爷一条新的木板。请给海蒂爷爷想想办法,把新木板插入合适的位置,把奇怪的木桶完成。

如果新木板有多个位置可以插入时,则请放置在下标最小的位置。如 1 2 3 1 插入 1,预期输出结果为 1 1 2 3 1,而不是 1 2 3 1 1。

输入描述

  • 原始木板列表长度n,其中1≤n≤400
  • 原始木板列表boards,满足循环非递减条件,0≤boards[i]≤10000
  • 新木板的长度newBoardLen,0≤newBoardLen≤10000
  • 输出描述

    返回插入新数据后的boards列表。

    样例输入

    4

    2 3 4 2

    1

    样例输出

    2 3 4 1 2

    样例说明1

    新增木板长度为1,只有插在原第3块和第4块木板之间,才能满足循环非递减规律。

    参考题解

    解题思路:

    1. 理解循环非递减的判定条件:整个环中最多只能有一个"下降点"
    2. 枚举所有可能的插入位置(共n+1个位置)
    3. 在每个位置插入新木板,生成新序列
    4. 检查新序列是否满足循环非递减条件
    5. 找到第一个满足条件的位置即可

    C++:

    #include <bits/stdc++.h>
    using namespace std;
    
    bool check(vector<int>& arr) {
        int n = arr.size();
        if (n <= 1) return true;
        
        int drop_count = 0;
        for (int i = 0; i < n; i++) {
            if (arr[i] > arr[(i + 1) % n]) {
                drop_count++;
            }
        }
        
        return drop_count <= 1;
    }
    
    int main() {
        int n;
        cin >> n;
        vector<int> boards(n);
        for (int i = 0; i < n; i++) {
            cin >> boards[i];
        }
        int newBoardLen;
        cin >> newBoardLen;
        
        for (int i = 0; i <= n; i++) {
            vector<int> temp_boards = boards;
            temp_boards.insert(temp_boards.begin() + i, newBoardLen);
            
            if (check(temp_boards)) {
                for (int j = 0; j < temp_boards.size(); j++) {
                    if (j > 0) cout << " ";
                    cout << temp_boards[j];
                }
                cout << endl;
                break;
            }
        }
        
        return 0;
    }
    

    Java:

    import java.util.*;
    
    public class Main {
        public static boolean check(List<Integer> arr) {
            int n = arr.size();
            if (n <= 1) return true;
            
            int dropCount = 0;
            for (int i = 0; i < n; i++) {
                if (arr.get(i) > arr.get((i + 1) % n)) {
                    dropCount++;
                }
            }
            
            return dropCount <= 1;
        }
        
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            List<Integer> boards = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                boards.add(sc.nextInt());
            }
            int newBoardLen = sc.nextInt();
            
            for (int i = 0; i <= n; i++) {
                List<Integer> tempBoards = new ArrayList<>(boards);
                tempBoards.add(i, newBoardLen);
                
                if (check(tempBoards)) {
                    for (int j = 0; j < tempBoards.size(); j++) {
                        if (j > 0) System.out.print(" ");
                        System.out.print(tempBoards.get(j));
                    }
                    System.out.println();
                    break;
                }
            }
        }
    }
    

    Python:

    import sys
    
    def check(arr):
        n = len(arr)
        if n <= 1:
            return True
        
        drop_count = 0
        for i in range(n):
            if arr[i] > arr[(i + 1) % n]:
                drop_count += 1
        
        return drop_count <= 1
    
    def main():
        n = int(sys.stdin.readline().strip())
        boards = list(map(int, sys.stdin.readline().strip().split()))
        newBoardLen = int(sys.stdin.readline().strip())
        
        for i in range(n + 1):
            temp_boards = boards[:]
            temp_boards.insert(i, newBoardLen)
            
            if check(temp_boards):
                print(*temp_boards)
                break
    
    main()
    

    第二题:关灯方案

    老旧小区需要关闭一排灯,由于接线混乱,按某个灯的开关时可能会同步影响多个灯的状态,被影响的灯的状态会发生反转,即原先亮着的灯会关闭,而关闭的灯会打开。

    已知第i个开关除了改变i号灯的状态之外,还会额外影响多个灯的状态;请问是否存在方案使得所有的灯都关闭。如果无解则输出-1;有解时输出选择按开关数量最小的方案,如果数量相同再比较字典序最小的方案。

    输入描述

  • 第1行两个整数n m,表示n个灯(每个灯一个开关),m个额外的影响关系。1≤n≤20,0≤m≤100
  • 第2行n个整数,表示灯的初始状态,0≤status[i]≤1,0表示关闭,1表示开启
  • 第3行到第m+2行:两个整数u v,表示操作灯u时会额外影响灯v。输入保证不重复。1≤u,v≤n
  • 输出描述

  • 如果无解,输出-1
  • 如果有解,输出一行升序整数序列,用空格隔开
  • 如果有多个解,优先选择按下开关数量最少的方案;若数量相同,选择字典序最小的方案
  • 样例输入

    2 2

    0 1

    1 2

    2 1

    样例输出

    -1

    样例说明1

    两盏灯互相影响,无法全部关闭。

    参考题解

    解题思路:

    1. 使用状态压缩,用二进制位表示灯的状态和开关的影响范围
    2. 暴力枚举所有可能的开关组合(2^n种情况)
    3. 对于每个组合,模拟按下开关后的最终状态
    4. 检查最终状态是否为0(所有灯关闭)
    5. 选择开关数量最少、字典序最小的方案

    C++:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int a, b;
        cin >> a >> b;
        
        int h = 0;
        for (int i = 0; i < a; i++) {
            int val;
            cin >> val;
            if (val == 1) {
                h |= (1 << i);
            }
        }
        
        vector<int> d(a, 0);
        for (int k = 0; k < a; k++) {
            d[k] |= (1 << k);
        }
        
        for (int i = 0; i < b; i++) {
            int m, n;
            cin >> m >> n;
            d[m - 1] |= (1 << (n - 1));
        }
        
        vector<int> o;
        bool p = false;
        
        for (int q = 0; q < (1 << a); q++) {
            int r = h;
            for (int s = 0; s < a; s++) {
                if ((q >> s) & 1) {
                    r ^= d[s];
                }
            }
            
            if (r == 0) {
                vector<int> t;
                for (int u = 0; u < a; u++) {
                    if ((q >> u) & 1) {
                        t.push_back(u + 1);
                    }
                }
                
                if (!p) {
                    o = t;
                    p = true;
                } else {
                    if (t.size() < o.size() || (t.size() == o.size() && t < o)) {
                        o = t;
                    }
                }
            }
        }
        
        if (!p) {
            cout << -1 << endl;
        } else {
            for (int i = 0; i < o.size(); i++) {
                if (i > 0) cout << " ";
                cout << o[i];
            }
            cout << endl;
        }
        
        return 0;
    }
    

    Java:

    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int a = sc.nextInt();
            int b = sc.next

    剩余60%内容,订阅专栏后可继续查看/也可单篇购买

    2025 春招笔试合集 文章被收录于专栏

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

    全部评论

    相关推荐

    评论
    点赞
    收藏
    分享

    创作者周榜

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