华为笔试 华为秋招 华为笔试题 0924
笔试时间:2025年9月24日
往年笔试合集:
第一题:海蒂爷爷的木桶
海蒂爷爷想做一个奇怪的木桶。
他去山里砍了一些木柴并加工成高矮不一的木板,然后他把木板按高矮排好顺序,依次取出,竖在地上,排列成一个圆桶状。该圆桶满足循环单调非递减规律(即从第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。
输入描述
输出描述
返回插入新数据后的boards列表。
样例输入
4
2 3 4 2
1
样例输出
2 3 4 1 2
样例说明1
新增木板长度为1,只有插在原第3块和第4块木板之间,才能满足循环非递减规律。
参考题解
解题思路:
- 理解循环非递减的判定条件:整个环中最多只能有一个"下降点"
- 枚举所有可能的插入位置(共n+1个位置)
- 在每个位置插入新木板,生成新序列
- 检查新序列是否满足循环非递减条件
- 找到第一个满足条件的位置即可
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;有解时输出选择按开关数量最小的方案,如果数量相同再比较字典序最小的方案。
输入描述
输出描述
样例输入
2 2
0 1
1 2
2 1
样例输出
-1
样例说明1
两盏灯互相影响,无法全部关闭。
参考题解
解题思路:
- 使用状态压缩,用二进制位表示灯的状态和开关的影响范围
- 暴力枚举所有可能的开关组合(2^n种情况)
- 对于每个组合,模拟按下开关后的最终状态
- 检查最终状态是否为0(所有灯关闭)
- 选择开关数量最少、字典序最小的方案
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打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
