华为笔试 华为秋招 华为笔试题 1010
笔试时间:2025年10月10日
往年笔试合集:
第一题:魔法学院
魔法学院的一名学员在早晨起床时,发现有人在他的被子上施加了 n 道昏睡魔法。每施加一道魔法后,该学员的清醒值会减少 a_i;在每次魔法结束后,他会进行抵抗,使清醒值增加 b_i(只有当该道魔法完全施法结束后才增加)。
初始时,学员的清醒值为 m。
学员可以自行安排这些魔法的施放顺序,但如果在施放某道魔法后,学员的清醒值 ≤ 0,则认为学员挣脱失败。
判断:是否存在一种施法顺序,使学员在整个过程中清醒值始终大于零并成功逃脱。
输入描述
第一行:一个整数 T(1≤T≤10),表示数据组数。
对于每组数据:
- 第一行两个整数 n 和 m(1≤n≤100,1≤m≤10^6),分别表示施加的昏睡魔法次数和初始清醒值。
- 接下来 n 行每行两个整数 a_i 和 b_i(1≤a_i,b_i≤10^6),分别表示该魔法减少的清醒值和抵抗后增加的清醒值。
注意:每一对(a_i, b_i)绑定,不可分开,但施法的顺序可以自由安排。
输出描述
对于每一组数据,如果学员能摆脱昏睡魔法,输出:Yes 否则输出:No
样例输入
2
2 5
3 2
4 5
2 5
3 2
4 2
样例输出
Yes
No
样例说明:
样例1:
- 初始:清醒值 m = 5
- 魔法1:(a_1 = 3, b_1 = 2)
- 魔法2:(a_2 = 4, b_2 = 5)
- 顺序1:5 - 3 + 2 = 4,4 - 4 + 5 = 5 ✅ 成功
- 顺序2:5 - 4 + 5 = 6,6 - 3 + 2 = 5 ✅ 成功 至少有一种顺序成功,所以输出 Yes。
样例2:
- 初始清醒值 m = 5
- 魔法1:(a_1 = 3, b_1 = 2)
- 魔法2:(a_2 = 4, b_2 = 2)
- 顺序1:5 - 3 + 2 = 4,4 - 4 + 2 = 2 → 在施法过程中有一次 4 - 4 = 0,失败
- 顺序2:5 - 4 + 2 = 3,3 - 3 + 2 = 2 → 在施法过程中有一次 3 - 3 = 0,失败 无论顺序如何均失败,输出 No。
参考题解
解题思路:
关键点:在施法结束后立即增加 b_i,所以危险时刻发生在施法刚结束但还没增加 b_i 的瞬间。
将魔法分为两类:
- 增益型魔法:b_i ≥ a_i,这类魔法总体上会增加或保持清醒值,按 a_i 从小到大排序(先处理消耗小的)
- 损耗型魔法:b_i < a_i,这类魔法总体上会减少清醒值,按 b_i 从大到小排序(优先选择抵抗效果好的)
C++:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void solve() {
int x, y;
cin >> x >> y;
vector<pair<int, int>> g, b;
for (int i = 0; i < x; i++) {
int p, q;
cin >> p >> q;
if (q >= p) {
g.push_back({p, q});
} else {
b.push_back({p, q});
}
}
sort(g.begin(), g.end());
sort(b.begin(), b.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
return a.second > b.second;
});
long long v = y;
for (auto& [p, q] : g) {
if (v <= p) {
cout << "No" << endl;
return;
}
v = v - p + q;
}
for (auto& [p, q] : b) {
if (v <= p) {
cout << "No" << endl;
return;
}
v = v - p + q;
}
cout << "Yes" << endl;
}
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
solve();
}
return 0;
}
Java:
import java.util.*;
public class Solution {
public static void solve(Scanner sc) {
int x = sc.nextInt();
int y = sc.nextInt();
List<int[]> g = new ArrayList<>();
List<int[]> b = new ArrayList<>();
for (int i = 0; i < x; i++) {
int p = sc.nextInt();
int q = sc.nextInt();
if (q >= p) {
g.add(new int[]{p, q});
} else {
b.add(new int[]{p, q});
}
}
g.sort((a1, a2) -> a1[0] - a2[0]);
b.sort((a1, a2) -> a2[1] - a1[1]);
long v = y;
for (int[] pair : g) {
if (v <= pair[0]) {
System.out.println("No");
return;
}
v = v - pair[0] + pair[1];
}
for (int[] pair : b) {
if (v <= pair[0]) {
System.out.println("No");
return;
}
v = v - pair[0] + pair[1];
}
System.out.println("Yes");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
solve(sc);
}
sc.close();
}
}
Python:
import sys
def solve():
x, y = map(int, sys.stdin.readline().strip().split())
g = []
b = []
for _ in range(x):
p, q = map(int, sys.stdin.readline().strip().split())
if q >= p:
g.append((p, q))
else:
b.append((p, q))
g.sort()
b.sort(key=lambda t: t[1])
b.reverse()
v = y
for p, q in g:
if v <= p:
print("No")
return
v = v - p + q
for p, q in b:
if v <= p:
print("No")
return
v = v - p + q
print("Yes")
t = int(sys.stdin.readline().strip())
for _ in range(t):
solve()
第二题:坐火车iv
某旅行线路上有一辆有 M 节车厢的列车,所有车厢中都没人,现有 N 个旅行团需要搭乘该线路,其 ID 为 1~N。请给出具体的乘坐方案,满足使得各车厢间的乘客数量差异最小。
说明:乘客最多的车厢中的人数记作 max,乘客最少的车厢中的人数记作 min,需要满足 max-min 最小。
旅行团乘坐列车需要满足如下要求:
- 对于任意 i < j,车厢 i 中的任意旅行团的 ID 小于车厢 j 中任意旅行团的 ID。
- 同个车厢内的旅行团,他们的 ID 是连续的。
- 同个旅行团的成员必须在一个车厢内。
注:当只有一个车厢时,该车厢的乘客数既是最大乘客数,也是最小乘客数。
输入描述
第1行:N M,其中
- N 是旅行团个数,范围是 1 ≤ N ≤ 10^4
- M 是车厢个数,范围是 1 ≤ M ≤ min(N, 1000)
第2行:P_1 P_2 ... P_N,每个数字代表一个旅行团的成员个数,成员个数范围是 1 ≤ P_i ≤ 10^4
输出描述
输出乘客最多的车厢中的人数 max。
样例输入
3 3
1 6 4
样例输出
6
样例说明1: N=3,M=3:有3个旅行团,列车有3节车厢。成员人数分别为[1,6,4]。每个车厢都有旅行团时车厢人数差异才可能最小,考虑以下方案:
- 车厢1:团1,人数1
- 车厢2:团2,人数6
- 车厢3:团3,人数4 可知乘客最多的车厢人数为6。
参考题解
解题思路:
问题转化为:将数组P切成M段,使得最大段和最小。 这是一个经典的"最小化最大段和"问题,可以用二分答案解决。
二分搜索策略:
- 搜
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
