【秋招笔试】2025.08.19菜鸟秋招算法岗机考真题改编
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线100+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
题目一:图书馆座位分配问题
1️⃣:二分查找最大化最小值问题
2️⃣:通过数学推导验证分配方案的可行性
难度:中等
这道题目的关键在于理解"最大化最小值"的优化思想,通过二分查找和数学约束条件的分析,我们可以高效地找到最优解。核心是将问题转化为判定性问题:给定目标值,是否存在合法的分配方案。
题目二:魔法编码寻踪
1️⃣:利用BFS层层向下搜索所有可能的魔法编码
2️⃣:通过数学分析优化搜索范围,避免无效枚举
3️⃣:使用集合去重,确保每个编码只被处理一次
难度:中等
这道题目结合了数学分析和图搜索算法。关键观察是魔法编码的搜索范围有限,通过位数分析可以大大缩小搜索空间。BFS保证了按层次有序地发现所有相关编码。
题目三:星际联盟连接方案
1️⃣:利用数论中最大公约数的性质分析连通性
2️⃣:将图连通性问题转化为整除性问题
3️⃣:通过质因数分解计算因子个数
难度:中等偏难
这道题目巧妙地将图论问题转化为数论问题。关键洞察是:如果频率常数X能连通所有星球,则X必须整除所有能量差值的最大公约数。通过这个转化,复杂的图连通性判断变成了简单的因子计数问题。
01. 图书馆座位分配问题
问题描述
小兰是市图书馆的管理员,今天图书馆迎来了 位读者。为了提供良好的阅读环境,小兰准备了
个独立的阅读区域。图书馆提供两种类型的学习资料:文科类资料共有
本,理科类资料共有
本。
小兰需要将所有资料分配到这 个阅读区域中,但有以下限制条件:
- 每个阅读区域只能放置一种类型的资料,即文科类资料和理科类资料不能放在同一个区域
- 小兰希望让资料最少的区域拥有尽可能多的资料(即最大化最小值)
请帮助小兰计算,在满足上述条件下,资料最少的区域最多能分配到多少本资料?
输入格式
第一行包含三个正整数 ,分别表示阅读区域数量、文科类资料数量和理科类资料数量。
输出格式
输出一个整数,表示资料最少的区域能分配到的最大资料数量。
样例输入
5 7 3
3 100 200
样例输出
1
100
样例 | 解释说明 |
---|---|
样例1 | 有5个区域,7本文科资料,3本理科资料。最优分配:3个区域各放2本文科资料(共6本),1个区域放1本文科资料,1个区域放3本理科资料。最少资料数为1本 |
样例2 | 有3个区域,100本文科资料,200本理科资料。最优分配:1个区域放100本文科资料,2个区域各放100本理科资料。最少资料数为100本 |
数据范围
题解
这道题的核心是要理解"最大化最小值"这个概念。假设我们要让每个区域至少分配到 本资料,那么问题就变成了:能否找到一种分配方案,使得这个目标能够实现?
关键观察:如果我们设定目标值为 ,那么文科区域的数量
必须满足一定的范围。具体来说:
- 文科区域需要的资料总数:
,必须不超过
,即
- 理科区域需要的资料总数:
,必须不超过
,即
因此,合法的文科区域数量 需要满足:
只要这个范围不为空(即左端点不大于右端点),就说明目标值 是可行的。
由于答案具有单调性(如果 可行,那么所有小于
的值也可行),我们可以用二分查找来找到最大的可行值。
时间复杂度:
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve():
n, a, b = map(int, input().split())
# 检查给定的最小值x是否可行
def check(x):
if x == 0:
return True
# 计算文科区域数量的合法范围
min_s = max(0, n - b // x) # 文科区域最少数量
max_s = min(n, a // x) # 文科区域最多数量
return min_s <= max_s
# 二分查找最大可行值
left, right = 0, max(a, b)
while left < right:
mid = (left + right + 1) // 2
if check(mid):
left = mid
else:
right = mid - 1
print(left)
solve()
- Cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
ll a, b;
cin >> n >> a >> b;
// 检查给定的最小值x是否可行
auto check = [&](ll x) -> bool {
if (x == 0) return true;
// 计算文科区域数量的合法范围
ll min_s = max(0LL, (ll)n - b / x); // 文科区域最少数量
ll max_s = min((ll)n, a / x); // 文科区域最多数量
return min_s <= max_s;
};
// 二分查找最大可行值
ll left = 0, right = max(a, b);
while (left < right) {
ll mid = (left + right + 1) / 2;
if (check(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
cout << left << '\n';
return 0;
}
- Java
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
long a = Long.parseLong(st.nextToken());
long b = Long.parseLong(st.nextToken());
// 二分查找最大可行值
long left = 0, right = Math.max(a, b);
while (left < right) {
long mid = (left + right + 1) / 2;
if (check(n, a, b, mid)) {
left = mid;
} else {
right = mid - 1;
}
}
System.out.println(left);
}
// 检查给定的最小值x是否可行
private static boolean check(int n, long a, long b, long x) {
if (x == 0) return true;
// 计算文科区域数量的合法范围
long minS = Math.max(0, n - b / x); // 文科区域最少数量
long maxS = Math.min(n, a / x); // 文科区域最多数量
return minS <= maxS;
}
}
02. 魔法编码寻踪
问题描述
小毛是一位密码学家,他发现了一种神奇的编码规律。对于任意一个正整数 ,如果存在另一个正整数
,使得
加上
的各位数字之和恰好等于
,那么
就被称为
的"魔法编码"。
小毛想要进行一次深度探索:
- 首先,找到给定编码
的所有"魔法编码",记为集合
- 然后,对集合
中的每个编码,继续寻找它们的"魔法编码",记为集合
- 重复这个过程,直到无法找到更多的魔法编码为止
请帮助小毛找出所有通过这种方式能够追溯到的魔法编码,并按从小到大的顺序输出。注意:相同的编码只输出一次。
输入格式
第一行包含一个正整数 ,表示初始的编码。
输出格式
在一行中按从小到大的顺序输出所有找到的魔法编码,编码之间用空格分隔。如果没有找到任何魔法编码,则输出空行。
样例输入
21
100
样例输出
3 6 12 15
86
样例 | 解释说明 |
---|---|
样例1 | 对于21:15(15+1+5=21✓)。 继续追溯:15的魔法编码有 12 (12 + 1 + 2 = 15 ✓) 继续追溯:12的魔法编码有 6 ( 6 + 6 = 12 ✓) 继续追溯:6的魔法编码有 3 (3 + 3 = 6) 对于3 没有可以追溯的魔法编码 |
样例2 | 对于100:直接魔法编码有86 剩余的没有别的编码了 |
数据范围
- 保证输出的魔法编码总数不超过
个
题解
这道题的关键是理解"魔法编码"的定义和如何高效地寻找它们。
对于一个给定的编码 ,我们要找到所有满足
的正整数
。注意到:
- 显然
(因为各位数字和至少为1)
- 对于
位数,各位数字和最大为
因此,对于编码 ,我们只需要在区间
中枚举所有可能的
,其中
是
的位数。
算法流程:
- 使用BFS(广度优先搜索)来层层向下寻找魔法编码
- 用集合记录已经访问过的编码,避免重复计算
- 对于每个编码,在合理的范围内枚举可能的魔法编码
- 将找到的新魔法编码加入队列继续搜索
时间复杂度:,其中
是计算各位数字和的时间
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def digit_sum(x):
"""计算x的各位数字之和"""
total = 0
while x > 0:
total += x % 10
x //= 10
return total
def solve():
n = int(input())
visited = set() # 记录已访问的编码
result = [] # 存储所有魔法编码
queue = [n] # BFS队列
visited.add(n) # 初始编码不输出,但用于继续搜索
while queue:
current = queue.pop(0)
digits = len(str(current)) # 当前编码的位数
# 魔法编码的搜索范围
start = max(1, current - 9 * digits)
for x in range(start, current):
if x + digit_sum(x) == current and x not in visited:
visited.add(x)
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力