大厂真题 / 荣耀
荣耀 5.7 笔试真题 - 通用岗
本场考试概述
考试时间:2026年5月7日 考试岗位:通用 难度评级:中等
考点分析:
- 第一题:数学 / 大整数(难度简单)
- 第二题:贪心 / 区间调度(难度中等)
- 第三题:DFS 回溯(难度中等)
建议策略:
- 第一题是签到题,Python 原生大整数 +
bit_length()一行搞定 - 第二题是经典区间调度模型,按结束时间排序 + 贪心扫描即可
- 第三题关键在于分析出每个房间只有两种人数,之后就是排列枚举
第 1 题:寻找 2 的次幂
题目描述
给定一个正整数 $N$($N$ 可达 $10^{1000}$),输出 $k$,使得 $2^k \leq N < 2^{k+1}$。
样例
输入
5
输出
2
思路分析
第一步:转化为二进制位数问题
$2^k$ 在二进制下是 1 后面跟 $k$ 个 0,共 $k+1$ 位。$2^k \leq N < 2^{k+1}$ 意味着 $N$ 的二进制恰好有 $k+1$ 位。所以答案就是 $N$ 的二进制位数减 1。
第二步:大整数处理
$N$ 最大有 1000 位十进制,普通 64 位整数存不下。Python 原生支持任意精度整数,直接用 int.bit_length() 求二进制位数即可。
题解代码
import sys
sys.set_int_max_str_digits(0)
n = int(input())
print(n.bit_length() - 1)
复杂度分析
时间复杂度:$O(L)$,$L$ 为 $N$ 的十进制位数(字符串转大整数的开销) 空间复杂度:$O(L)$,存储大整数
第 2 题:鸟巢场馆
题目描述
2008 年奥运会后,鸟巢场馆对外开放,各公司可以申请使用。每个公司提交一个使用时间段 $[s_i, e_i]$(闭区间),时间段重叠的公司不能同时安排(端点重合也算重叠)。设计方案使尽可能多的公司使用到鸟巢。
第一行整数 $n$ 表示公司数,第二行 $2n$ 个整数,每两个一组表示起止时间。
样例
输入
4
4 9 9 11 13 19 10 17
输出
2
思路分析
第一步:识别问题模型
给定 $n$ 个闭区间,选出尽可能多的区间使两两不重叠。这就是经典的”活动选择问题”(区间调度最大化)。
第二步:贪心策略
按结束时间从小到大排序。从前往后扫描,维护已选区间的最大结束时间 last_end。对于每个区间 $[s, e]$:若 $s > \text{last_end}$(严格大于,因为端点重合也算冲突),则选入并更新 last_end = e。
第三步:正确性
每次选结束最早的区间一定最优——选结束更晚的区间不会比当前选择更好,因为它只会占用更多时间,给后续留更少空间。这是经典贪心的交换论证。
以样例为例:4 个区间为 $[4,9], [9,11], [13,19], [10,17]$。按结束时间排序后为 $[4,9], [9,11], [10,17], [13,19]$。选 $[4,9]$ 后,$[9,11]$ 的起点 $9$ 不严格大于 $9$,跳过;$[10,17]$ 的起点 $10 > 9$,选入。最终选 2 个。
题解代码
import sys
input = sys.stdin.readline
def solve():
n = int(input())
nums = list(map(int, input().split()))
intervals = [(nums[2 * i], nums[2 * i + 1]) for i in range(n)]
# 按结束时间排序
intervals.sort(key=lambda x: (x[1], x[0]))
cnt = 0
last_end = -10**18
for s, e in intervals:
if s > last_end:
cnt += 1
last_end = e
print(cnt)
solve()
复杂度分析
时间复杂度:$O(n \log n)$,排序为瓶颈 空间复杂度:$O(n)$,存储区间数组
第 3 题:房间安排
题目描述
有 $m$ 个房间,$n$ 个人需要入住。每个房间最多住 5 人,且任意两个房间的人数差不超过 1。列出所有满足条件的安排方案(房间有先后顺序,不同排列视为不同方案)。
输入一行,格式为 m,n。输出第一行为剩余未安排的人数,之后每行一种方案。参数异常时输出 invalid。
样例
输入
7,11
输出
0
2,2,2,2,1,1,1
2,2,2,1,2,1,1
2,2,2,1,1,2,1
2,2,2,1,1,1,2
2,2,1,2,2,1,1
...
1,1,1,2,2,2,2
思路分析
第一步:计算实际能安排的人数
每个房间最多 5 人,$m$ 个房间最多装 $5m$ 人。若 $n > 5m$,多出来的人无法安排。实际安排人数 $\text{used} = \min(n, 5m)$,剩余 $\text{left} = n - \text{used}$。
第二步:确定每个房间住几人
将 $\text{used}$ 人平均分到 $m$ 个房间:$\text{base} = \text{used} \div m$(整除),余数 $\text{extra} = \text{used} \mod m$。有 $\text{extra}$ 个房间住 $\text{base}+1$ 人,其余 $m - \text{extra}$ 个房间住 $\text{base}$ 人。任意两房间差值恰好为 0 或 1,满足公平约束。
第三步:DFS 枚举所有排列
问题变成:$m$ 个位置里选 $\text{extra}$ 个放 $\text{base}+1$,其余放 $\text{base}$。用回溯法逐个位置填数,每个位置先尝试填大数(保证输出顺序与样例一致),再尝试填小数。
题解代码
import sys
def solve():
s = input().strip()
try:
parts = s.split(",")
if len(parts) != 2:
print("invalid")
return
m = int(parts[0])
n = int(parts[1])
except:
print("invalid")
return
if m <= 0 or n < 0:
print("invalid")
return
used = min(n, m * 5)
left = n - used
base = used // m
extra = used % m
results = []
path = []
def dfs(idx, high_left, low_left):
if idx == m:
results.append(",".join(map(str, path)))
return
# 先放 base+1 保证输出顺序
if high_left > 0:
path.append(base + 1)
dfs(idx + 1, high_left - 1, low_left)
path.pop()
if low_left > 0:
path.append(base)
dfs(idx + 1, high_left, low_left - 1)
path.pop()
dfs(0, extra, m - extra)
print(left)
print('\n'.join(results))
solve()
复杂度分析
时间复杂度:$O(\binom{m}{\text{extra}} \cdot m)$,共 $\binom{m}{\text{extra}}$ 个方案,每个方案长度 $m$ 空间复杂度:$O(m)$,递归栈深度
小结
- 第一题考察大整数处理:利用 Python 原生大整数和
bit_length()方法一行求解 - 第二题是经典区间调度贪心:按结束时间排序,每次贪心选最早结束的区间
- 第三题本质是组合排列枚举:先分析出每个房间只有两种可能人数,再用 DFS 回溯列出所有排列