【春招笔试】2025.5.22携程春招最后一场笔试!
✅ 春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题(建议用时:90分钟/套)
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线80+套真题改编解析,后续会持续更新的
春秋招合集 -> 互联网必备刷题宝典🔗
题目一:小兰的密码解码器
1️⃣:理解字母间距离计算公式
2️⃣:对每个关键字母计算到目标字母的解码复杂度
3️⃣:求和得到总解码复杂度
难度:简单
这道题目的关键在于理解"解码复杂度"的定义,即两个字母之间的距离等于它们在字母表中位置差的绝对值减去 1,如果结果为负数则取 0。通过简单的数学计算,可以快速得到答案。
题目二:小毛的数组优化系统
1️⃣:理解协调操作的本质:可以将任意两个元素替换为它们的最大公约数
2️⃣:发现所有元素最终都能变成整个数组的最大公约数
3️⃣:计算 n × gcd(所有元素) 得到最小总和
难度:中等
这道题目需要理解数学上的性质:通过协调操作,整个数组的所有元素最终都能变成数组全体元素的最大公约数。关键insight是任意两个数都可以被替换为它们的最大公约数,从而实现全局最小化。
题目三:小基的数据分析系统
1️⃣:枚举所有可能的分割点
2️⃣:预处理前缀和数组和后缀按位或数组
3️⃣:计算每个分割点的指标差异度,取最小值
难度:中等
这道题目考查数组的分割优化问题。通过预处理前缀和与后缀按位或,可以在 O(n) 时间内枚举所有分割点并找到最优解。关键在于理解求和指标与融合指标的定义和高效计算方法。
题目四:小柯的二进制编码调整器
1️⃣:利用 2^k mod 3 的数学性质快速计算二进制数模 3
2️⃣:根据位权奇偶性和字符值将位置分为四类
3️⃣:根据当前模值确定需要的交换类型并输出结果
难度:中等偏难
这道题目结合了数论和位运算的知识。关键在于理解 2^k mod 3 的周期性规律,以及交换操作对模运算的影响。通过数学分析,可以将复杂的搜索问题转化为 O(n) 的分类判断问题。
01. 小兰的密码解码器
问题描述
小兰最近迷上了密码学,她设计了一个特殊的字母解码系统。在这个系统中,她需要根据三个关键字母的编码信息来计算它们与目标字母之间的"解码复杂度"。
解码复杂度的定义如下:对于三个关键字母和一个目标字母,每个关键字母到目标字母的解码难度等于它们在字母表中位置差的绝对值减去 (如果结果小于
,则难度为
)。三个字母的总解码复杂度就是它们各自解码难度的总和。
小兰想知道,对于给定的三个关键字母和目标字母,总的解码复杂度是多少。
输入格式
第一行包含一个正整数 (
),表示测试用例的数量。
对于每个测试用例:
- 第一行包含三个小写字母
、
、
,用空格分隔,表示三个关键字母。
- 第二行包含一个小写字母
,表示目标字母。
输出格式
对于每个测试用例,输出一行,包含一个整数,表示总的解码复杂度。
样例输入
3
b b a
a
b a c
a
a a a
z
样例输出
0
1
72
样例1 | 字母 |
样例2 | 字母 |
样例3 | 三个字母 |
数据范围
- 所有字母均为小写英文字母
题解
这道题本质上是计算字母间距离的问题。关键在于理解"解码复杂度"的定义:两个字母之间的距离等于它们在字母表中位置差的绝对值减去 ,如果结果为负数则取
。
具体思路如下:
- 对于每个关键字母,计算它与目标字母的位置差
- 取绝对值后减去
,如果结果小于
则取
- 将三个字母的结果相加得到总复杂度
时间复杂度为 ,空间复杂度为
。
对于样例解释:
- 样例1:
和
的位置分别是
和
,距离为
- 样例2:
和
的位置分别是
和
,距离为
- 样例3:
和
的位置分别是
和
,距离为
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def calc_dist(ch1, ch2):
# 计算两个字母间的解码复杂度
diff = abs(ord(ch1) - ord(ch2)) - 1
return max(0, diff)
t = int(input())
for _ in range(t):
line1 = input().split()
a, b, c = line1[0], line1[1], line1[2]
p = input().strip()
# 计算总解码复杂度
total = calc_dist(a, p) + calc_dist(b, p) + calc_dist(c, p)
print(total)
- Cpp
#include <iostream>
#include <cmath>
using namespace std;
int calc_dist(char x, char y) {
// 计算字母间解码复杂度
int diff = abs(x - y) - 1;
return diff > 0 ? diff : 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
char a, b, c, p;
cin >> a >> b >> c >> p;
// 计算三个字母的总复杂度
int total = calc_dist(a, p) + calc_dist(b, p) + calc_dist(c, p);
cout << total << endl;
}
return 0;
}
- Java
import java.util.Scanner;
public class Main {
// 计算字母间解码复杂度
private static int calcDist(char ch1, char ch2) {
int diff = Math.abs(ch1 - ch2) - 1;
return Math.max(0, diff);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while (t-- > 0) {
char a = sc.next().charAt(0);
char b = sc.next().charAt(0);
char c = sc.next().charAt(0);
char p = sc.next().charAt(0);
// 计算总解码复杂度
int total = calcDist(a, p) + calcDist(b, p) + calcDist(c, p);
System.out.println(total);
}
sc.close();
}
}
02. 小毛的数组优化系统
问题描述
小毛负责一个数据处理系统,他需要对输入的数组进行优化处理。系统允许执行一种特殊的"协调操作":选择数组中的任意两个元素,将它们替换为两个新的正整数,但要求这两个新整数的最大公约数必须等于原来两个元素的最大公约数。
小毛的目标是通过多次协调操作,使得数组所有元素的总和达到最小值。他想知道,经过任意次优化操作后,数组元素总和的最小可能值是多少。
输入格式
第一行包含一个正整数 (
),表示测试用例的数量。
对于每个测试用例:
- 第一行包含一个正整数
(
),表示数组的长度。
- 第二行包含
个正整数
(
),表示数组的元素。
保证所有测试用例中 的总和不超过
。
输出格式
对于每个测试用例,输出一行,包含一个整数,表示经过优化后能够得到的最小数组元素总和。
样例输入
2
2
1 2
3
3 7 9
样例输出
2
3
样例1 | 数组 |
样例2 | 数组 |
数据范围
- 所有测试用例中
的总和不超过
题解
这道题的关键insight是理解协调操作的本质。当我们选择两个元素 和
,将它们替换为
和
,且要求
时,我们可以选择
。
通过多次这样的操作,我们可以将整个数组的所有元素都变成数组全体元素的最大公约数。具体分析:
- 任意两个元素都可以被替换为它们的最大公约数
- 通过连续的操作,所有元素最终都能变成整个数组的最大公约数
- 因此最小总和就是
算法步骤:
- 计算数组所有元素的最大公约数
- 返回
乘以这个最大公约数
时间复杂度为 ,其中
是数组元素的最大值。
参考代码
- Python
import sys
import math
input = lambda: sys.stdin.readline().strip()
def gcd_list(arr):
# 计算数组所有元素的最大公约数
result = arr[0]
for i in range(1, len(arr)):
result = math.gcd(result, arr[i])
return result
t = int(input())
for _ in range(t):
n = int(input())
arr = list(map(int, input().split()))
# 计算最小总和
g = gcd_list(arr)
print(n * g)
- Cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using ll = long long;
ll gcd_func(ll a, ll b) {
// 计算两个数的最大公约数
return b == 0 ? a : gcd_func(b, a % b);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
ll g;
cin >> g;
// 计算所有元素的最大公约数
for (int i = 1; i < n; i++) {
ll x;
cin >> x;
g = gcd_func(g, x);
}
cout << g * n << endl;
}
return 0;
}
- Java
import java.util.Scanner;
public class Main {
// 计算两个数的最大公约数
private static long gcdFunc(long a, long b) {
return b == 0 ? a : gcdFunc(b, a % b);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while (t-- > 0) {
int n = sc.nextInt();
long g = sc.nextLong();
// 计算所有元素的最大公约数
for (int i = 1; i < n; i++) {
long x = sc.nextLong();
g = gcdFunc(g, x);
}
System.out.println(g * n);
}
sc.close();
}
}
03. 小基的数据分析系统
问题描述
小基在一家数据分析公司工作,她需要处理一个特殊的数据集分割任务。给定一个包含 个数值的数据集,她需要将其分割成恰好两个非空的子集。
对于任意子集,定义两个重要指标:
- 求和指标
:子集中所有数值的总和
- 融合指标
:子集中所有数值的按位或运算结果
小基的目标是找到一种分割方案,使得两个子集的"指标差异度"最小。指标差异度定义为:。
她想知道,在所有可能的分割方案中,最小的指标差异度是多少。
输入格式
第一行包含一个正整数 (
),表示测试用例的数量。
对于每个测试用例:
- 第一行包含一个正整数
(
),表示数据集的大小。
- 第二行包含
个非负整数
(
),表示数据集中的数值。
保证所有测试用例中 的总和不超过
。
输出格式
对于每个测试用例,输出一行,包含一个整数,表示最小的指标差异度。
样例输入
1
5
1 2 3 4 5
样例输出
1
样例1 | 将数据集分割为前半部分 和后半部分 。前半部分的求和指 |
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力