【秋招笔试】2025.08.27小红书秋招笔试真题改编
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线140+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
题目一:魔法数字工厂
1️⃣:预处理所有可能的连续正整数乘积,存储在哈希表中
2️⃣:枚举长度3到12的连续数字序列,计算乘积并判断是否超出范围
3️⃣:对每次查询,直接在哈希表中查找答案
难度:中等
这道题目的关键在于理解连续正整数乘积的性质,通过预处理避免重复计算。由于数据范围限制,只需要考虑长度不超过12的连续序列,总的魔法数字数量很少,使得哈希表查询非常高效。
题目二:智能监控网络部署
1️⃣:将问题转化为经典的区间覆盖问题
2️⃣:计算每个节点的可连接区间范围
3️⃣:使用贪心算法,按区间右端点排序后依次选择控制中心位置
难度:中等
这道题目需要理解区间覆盖的贪心策略。通过将每个监控节点的传输范围转化为线段,问题变成了经典的用最少点覆盖所有线段的问题。贪心选择在区间右端点放置控制中心是最优策略。
题目三:图书馆座位重排系统
1️⃣:理解三元环操作的本质,即循环交换三个位置的字符
2️⃣:使用线段树支持区间最小值查询
3️⃣:从左到右枚举每个位置,寻找能够改善字典序的操作
难度:中等偏难
这道题目结合了字符串操作和数据结构优化。关键在于理解操作的实质是三元环交换,并且要贪心地寻找能够最大化改善字典序的操作。线段树的使用使得区间查询的复杂度降低到 ,确保了整体算法的效率。
01. 魔法数字工厂
问题描述
小兰在她的魔法数字工厂里工作,这个工厂专门生产一种特殊的数字——"魔法数字"。一个正整数 被称为魔法数字,当且仅当它同时满足以下两个条件:
-
可以将
写作一个公差为
且所有元素都是正整数的等差数列的乘积,例如,
可以写作
;
-
上述等差数列的长度至少为
。
现在工厂收到了多个订单,每次客户会询问一个正整数 是否为魔法数字。请帮助小兰判断这些数字是否符合要求。
输入格式
第一行包含一个正整数 (
),表示询问的次数。
接下来 行,每行包含一个正整数
(
),表示一次数字查询。
输出格式
对于每次查询,输出一行:如果 是魔法数字,输出
YES
;否则,输出 NO
。
样例输入
3
6
2
24
样例输出
YES
NO
YES
样例 | 解释说明 |
---|---|
样例1 | |
样例2 | |
样例3 |
数据范围
题解
这道题的关键在于理解什么是魔法数字。魔法数字就是连续的至少3个正整数的乘积。
首先分析数据范围,如果连续数字的个数 ,那么最小的乘积
,超出了题目范围。所以我们只需要考虑长度为
到
的情况。
对于每个固定的长度 ,我们可以枚举起始位置
,计算乘积
。当乘积超过
时就可以停止了,因为继续增大
只会让乘积更大。
由于满足条件的魔法数字总数不多(只有几千个),我们可以预处理所有的魔法数字,存储在哈希表中,这样每次查询的时间复杂度就是 。
具体步骤:
- 预处理:枚举长度
从
到
,对每个长度枚举起始位置
,计算连续
个数的乘积
- 将所有不超过
的乘积存入哈希表
- 对于每次查询,直接在哈希表中查找即可
时间复杂度:预处理 (因为数量很少),每次查询
。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 预处理所有魔法数字
MAX_VAL = 10**9
magic_set = set()
# 枚举长度从3到12
for length in range(3, 13):
k = 1
while True:
prod = 1
# 计算连续length个数的乘积
for i in range(length):
prod *= (k + i)
if prod > MAX_VAL:
break
if prod > MAX_VAL:
break
magic_set.add(prod)
k += 1
t = int(input())
for _ in range(t):
x = int(input())
if x in magic_set:
print("YES")
else:
print("NO")
- Cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const long long MAX_VAL = 1000000000LL;
unordered_set<long long> magic_nums;
// 枚举长度从3到12
for (int len = 3; len <= 12; ++len) {
for (long long k = 1; ; ++k) {
long long prod = 1;
bool overflow = false;
// 计算连续len个数的乘积
for (int i = 0; i < len; ++i) {
if (prod > MAX_VAL / (k + i)) { // 防止溢出
overflow = true;
break;
}
prod *= (k + i);
}
if (overflow || prod > MAX_VAL) {
break;
}
magic_nums.insert(prod);
}
}
int t;
cin >> t;
while (t--) {
long long x;
cin >> x;
cout << (magic_nums.count(x) ? "YES" : "NO") << "\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));
final long MAX_VAL = 1000000000L;
Set<Long> magicNums = new HashSet<>();
// 枚举长度从3到12
for (int len = 3; len <= 12; len++) {
for (long k = 1; ; k++) {
long prod = 1;
boolean overflow = false;
// 计算连续len个数的乘积
for (int i = 0; i < len; i++) {
if (prod > MAX_VAL / (k + i)) { // 防止溢出
overflow = true;
break;
}
prod *= (k + i);
}
if (overflow || prod > MAX_VAL) {
break;
}
magicNums.add(prod);
}
}
int t = Integer.parseInt(br.readLine());
for (int i = 0; i < t; i++) {
long x = Long.parseLong(br.readLine());
System.out.println(magicNums.contains(x) ? "YES" : "NO");
}
}
}
02. 智能监控网络部署
问题描述
小基公司正在建设一套智能监控网络系统,系统包含 个监控节点,编号从
到
,这些节点按顺序排列在一条直线上。
第 个节点与相邻节点(即编号
和
的节点,如果存在)通过网络链路相连。
每个监控节点都有其信号传输范围限制,第 个节点发送的数据最多只能经过
条链路到达其他节点。
现在需要在若干节点部署控制中心,确保每个监控节点都能在不超过其传输范围限制的情况下连接到至少一个控制中心。
请计算最少需要部署多少个控制中心。
输入格式
第一行包含一个正整数 (
),表示测试数据组数。
对于每组测试数据:
第一行包含一个正整数 (
),表示监控节点数。
第二行包含 个非负整数
(
),表示第
个节点的信号传输范围限制。
所有测试数据的 之和不超过
。
输出格式
对于每组测试数据,输出一个整数,表示最少需要部署的控制中心数量。
样例输入
3
7
4 0 0 1 3 1 3
5
0 1 1 1 0
4
0 0 0 0
样例输出
3
3
4
样例 | 解释说明 |
---|---|
样例1 | 节点覆盖区间分别为 |
样例2 | 节点覆盖区间分别为 |
样例3 | 每个节点的传输范围都是 |
数据范围
- 所有测试数据的
之和不超过
题解
这道题可以转化为经典的区间覆盖问题。每个监控节点 都有一个可以连接到控制中心的区间范围,即
。我们需要选择尽量少的点(控制中心位置),使得每个区间都包含至少一个点。
这是一个经典的贪心问题,可以用区间打点的贪心算法来解决:
- 将所有区间按照右端点升序排序
- 依次扫描每个区间,如果当前区间已经被之前选择的控制中心覆盖,则跳过
- 否则,在当前区间的右端点位置放置一个控制中心(这样能覆盖尽可能多的后续区间)
为什么这个贪心策略是正确的?因为对于任何一个区间,在其右端点放置控制中心总是最优的选择,这样既能覆盖当前区间,又能为后续可能的区间提供最大的覆盖机会。
算法步骤:
- 对每个节点
,计算其可连接的区间
- 将所有区间按右端点排序
- 贪心选择控制中心位置:从左到右扫描,如果当前区间没有被已选择的控制中心覆盖,就在其右端点放置新的控制中心
时间复杂度:,主要是排序的复杂度。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
t = int(input())
for _ in range(t):
n = int(input())
d = list(map(int, input().split()))
# 计算每个节点的覆盖区间
segs = []
for i in range(n):
left = max(1, i + 1 - d[i]) # 转换为1-based
right = min(n, i + 1 + d[i])
segs.append((left, right))
# 按右端点排序
segs.sort(key=lambda x: x[1])
# 贪心选择控制中心
last_pos = -1 # 上一个控制中心的位置
ans = 0
for left, right in segs:
if last_pos >= left: # 已经被覆盖
continue
# 在右端点放置控制中心
ans += 1
last_pos = right
print(ans)
- Cpp
#include <bits/stdc++.h>
using namespace std;
struct Interval {
int l, r;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力