【秋招笔试】2025.08.23淘天算法岗秋招笔试真题
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线140+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
题目一:古钟修复大师
1️⃣:理解问题本质 - 古钟只会漏响,不会额外响铃
2️⃣:数学转化 - 所有观测时刻必须是原始间隔的整数倍
3️⃣:求解最大公约数 - 计算除第一个时刻外所有时刻的GCD
难度:简单
这道题的关键在于理解古钟故障的特性,将实际问题转化为数学问题。通过观察得出所有响铃时刻都是原始周期的整数倍,问题转化为求最大公约数。算法简洁高效,时间复杂度为O(n log A)。
题目二:智能加密矩阵系统
1️⃣:分析加密操作的累计效果 - 奇数次操作等价于异或一次
2️⃣:利用对角线信息进行逻辑推理 - 确定每行每列的加密状态
3️⃣:枚举可能的状态组合 - 四种情况的系统性验证
难度:中等
这道题结合了位运算和逻辑推理,需要理解异或操作的性质和矩阵变换规律。关键洞察是通过对角线信息可以独立确定每行每列的状态,然后利用状态组合快速回答查询。时间复杂度为O(n+q)。
题目三:数据库清洗优化系统
1️⃣:问题建模 - 保留连续子数组,删除两端,修改中间问题记录
2️⃣:成本函数优化 - 利用前缀和技巧转化为最优化问题
3️⃣:贪心策略求解 - 枚举右端点,维护最小左值
难度:中等偏难
这道题考查动态规划和贪心算法的综合运用。核心思想是将问题转化为选择最优保留区间,通过数学变换和前缀和优化,实现O(n)时间复杂度的高效求解。体现了算法设计中化繁为简的重要思想。
01. 古钟修复大师
问题描述
小兰是一位著名的古董钟表修复大师。最近,她接到了一个特殊的修复委托:一座有着悠久历史的古钟。
这座古钟原本应该按照固定的时间间隔 秒响铃,即在时刻
响铃。然而,由于年代久远,机械部件已经老化,古钟经常会漏响,但绝不会在不该响的时候额外响铃。
现在,小兰观测到古钟在时刻 响了铃。她知道
,且这些时刻严格递增。
作为修复大师,小兰想要确定这座古钟原本设计的最大可能响铃间隔是多少秒,以便进行精确的修复工作。
输入格式
第一行包含一个正整数 (
),表示观测到的响铃次数。
第二行包含 个整数
(
),表示每次响铃的时刻。保证
,且序列严格单调递增。
输出格式
输出一个整数,表示古钟原本设计的最大可能响铃间隔。
样例输入
3
0 1 3
样例输出
1
数据范围
-
-
-
,且序列严格单调递增
样例 | 解释说明 |
---|---|
样例1 | 观测到响铃时刻为0,1,3。如果原始间隔为1秒,则古钟应在0,1,2,3,4,...响铃,其中时刻2被漏掉了。这是可能的最大间隔 |
题解
这道题的核心思想是:既然古钟只会漏响而不会额外响铃,那么观测到的每个响铃时刻都必须是原始间隔T的整数倍。
具体分析:
- 问题本质:设原始响铃间隔为T秒,则古钟本应在时刻
响铃
- 约束条件:由于只会漏响,观测到的每个时刻
都必须是某个
的形式
- 数学转化:这意味着T必须能整除所有的
(
总是能被任何正整数整除)
因此,满足条件的最大T就是 的最大公约数。
算法步骤:
- 读入所有观测时刻
- 计算除第一个时刻外所有时刻的最大公约数
- 输出结果
时间复杂度为 ,其中A是数组中的最大值。对于给定的数据范围,这个复杂度完全可以接受。
参考代码
- Python
import sys
import math
input = lambda: sys.stdin.readline().strip()
def solve():
"""古钟修复问题求解函数"""
n = int(input())
times = list(map(int, input().split()))
# 计算除第一个时刻外所有时刻的最大公约数
result = 0
for i in range(1, n):
result = math.gcd(result, times[i])
print(result)
if __name__ == "__main__":
solve()
- Cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int cnt;
cin >> cnt;
vector<ll> bell_times(cnt);
for (int i = 0; i < cnt; i++) {
cin >> bell_times[i];
}
// 计算从第二个时刻开始的所有时刻的最大公约数
ll gcd_result = 0;
for (int i = 1; i < cnt; i++) {
gcd_result = __gcd(gcd_result, bell_times[i]);
}
cout << gcd_result << "\n";
return 0;
}
- Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int ringCount = Integer.parseInt(reader.readLine());
String[] timeStr = reader.readLine().split(" ");
long[] ringTimes = new long[ringCount];
for (int i = 0; i < ringCount; i++) {
ringTimes[i] = Long.parseLong(timeStr[i]);
}
// 计算除第一个时刻外所有时刻的最大公约数
long gcdVal = 0;
for (int i = 1; i < ringCount; i++) {
gcdVal = gcd(gcdVal, ringTimes[i]);
}
System.out.println(gcdVal);
}
// 计算最大公约数的辅助函数
private static long gcd(long a, long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
}
02. 智能加密矩阵系统
问题描述
小毛负责维护一套高级的智能加密矩阵系统。该系统包含一个 的数据矩阵,以及两组加密密钥:行密钥数组
和列密钥数组
。所有密钥都是互不相同的正整数。
系统的工作原理如下:
-
初始时,矩阵中所有元素都为
-
系统支持两种加密操作:
-
行加密:选择第
行,将该行所有元素与行密钥
进行异或运算
-
列加密:选择第
列,将该列所有元素与列密钥
进行异或运算
-
经过一系列未知的加密操作后,小毛只能观测到矩阵主对角线上的最终加密值:第 个对角线位置的值为
。
现在,小毛需要根据这些信息来回答 个查询,每个查询要求确定矩阵中位置
的加密值。
输入格式
第一行包含两个正整数 和
(
),分别表示矩阵维度和查询次数。
第二行包含 个互不相同的正整数
(
),表示行密钥数组。
第三行包含 个互不相同的正整数
(
),表示列密钥数组。
第四行包含 个整数
(
),表示主对角线的最终加密值。
接下来 行,每行包含两个正整数
和
(
),表示查询的位置。
输出格式
对于每个查询,输出一行一个整数,表示位置 的加密值。
样例输入
2 1
1 2
3 4
1 4
1 2
3 2
1 2 4
8 16 32
1 16 36
1 3
2 3
样例输出
5
33
32
数据范围
-
-
,且
和
互不相同
-
样例 | 解释说明 |
---|---|
样例1 | 通过逻辑推理可确定行1和列2都进行了奇数次加密操作,所以(1,2)位置的值为 |
样例2 | 根据对角线值可推断出各行列的加密状态,进而计算出查询位置的值 |
题解
这道题的关键在于理解加密操作的累计效果和利用对角线信息进行逻辑推理。
核心观察:
- 操作累计效果:如果某行被加密了奇数次,其效果等价于与行密钥异或一次;偶数次则无效果
- 矩阵元素公式:位置
的最终值为:
,其中
和
是布尔值,表示第
行和第
列是否被奇数次加密
- 对角线约束:
解题步骤:
-
确定加密状态:对每个对角线位置
,尝试四种可能的
组合:
:要求
:要求
:要求
:要求
-
选择有效组合:题目保证至少有一种组合满足条件,选择任意一种即可
-
回答查询:对于查询
,计算
时间复杂度为 ,空间复杂度为
,能够高效处理大规模数据。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve():
"""智能加密矩阵系统求解函数"""
n, q = map(int, input().split())
x = [0] + list(map(int, input().split())) # 1-indexed
y = [0] + list(map(int, input().split())) # 1-indexed
z = [0] + list(map(int, input().split())) # 1-indexed
# 确定每行每列的加密状态
row_state = [0] * (n + 1) # 0或1
col_state = [0] * (n + 1) # 0或1
for i in range(1, n + 1):
# 尝试四种可能的状态组合
if z[i] == 0:
row_state[i], col_state[i] = 0, 0
elif z[i] == y[i]:
row_state[i], col_state[i] = 0, 1
elif z[i] == x[i]:
row_state[i], col_state[i] = 1, 0
elif z[i] == (x[i] ^ y[i]):
row_state[i], col_state[i] = 1, 1
# 处理查询
for _ in range(q):
u, v = map(int, input().split())
# 计算位置(u,v)的加密值
val = (x[u] if row_state[u] else 0) ^ (y[v] if col_state[v] else 0)
print(val)
if __name__ == "__main__":
solve()
- Cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int dim, queries;
cin >> dim >> queries;
vector<int> row_keys(dim + 1), col_keys(dim + 1), diag_vals(dim + 1);
for (int i = 1; i <= dim; i++) {
cin >> row_keys[i];
}
for (int i = 1; i <= dim; i++) {
cin >> col_keys[i];
}
for (int i = 1; i <= dim; i++) {
cin >> diag_vals[i];
}
// 确定每行每列的加密状态
vector<bool> row_flag(dim + 1), col_flag(dim + 1);
for (int i = 1; i <= dim; i++) {
int target = diag_vals[i];
// 尝试所有可能的状
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力