华为笔试 华为秋招 华为笔试题 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等多种语言做法集合指南