【秋招笔试】2025.08.16科大讯飞秋招笔试机考改编题
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线110+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
题目一:图书馆书籍整理
1️⃣:分析装帧转换操作的奇偶性特征
2️⃣:根据操作次数与平装本数量的关系分情况讨论
3️⃣:利用贪心策略最大化精装本数量
难度:中等
这道题目的关键在于理解操作的奇偶性影响,通过数学分析可以发现对每本书进行奇数次操作会改变装帧类型,偶数次操作保持不变。运用贪心思想,优先转换平装本为精装本,当操作次数有余时考虑剩余操作的奇偶性。
题目二:音符序列调整
1️⃣:理解音高提升操作对相邻音符差值的影响
2️⃣:分析打破单调递增的必要条件
3️⃣:寻找最小操作区间长度的贪心策略
难度:中等
这道题目需要深入理解操作机制,发现区间操作本质上是让某个位置的音符相对于后继音符增加固定的音高差。通过数学推导可以得出,只有当存在相邻音符的音高差小于增量时才能打破单调性,且最优策略是选择长度为1的区间。
题目三:智能照明系统
1️⃣:利用异或运算的性质分析LED状态变化
2️⃣:采用数学公式化简大规模矩阵的二进制转换
3️⃣:运用快速幂和模运算优化大数计算
难度:中等偏难
这道题目结合了位运算、组合数学和模运算。关键在于发现每个LED的最终状态只依赖于所在行列的操作奇偶性,然后通过数学公式将大规模矩阵的计算转化为高效的数值运算,避免了直接模拟的时间复杂度问题。
01. 图书馆书籍整理
问题描述
小基 在图书馆工作,她需要整理一排书架上的书籍。书架上有 本书,每本书要么是精装本(用大写字母 H 表示),要么是平装本(用小写字母 s 表示)。
图书馆的规定是:为了美观,希望书架上精装本的数量尽可能多。小基 可以对书籍进行"装帧转换"操作:将一本精装本改为平装本,或将一本平装本改为精装本。
现在 小基 必须恰好进行 次装帧转换操作,请问最终书架上最多能有多少本精装本?
输入格式
第一行包含两个正整数 和
(
,
),分别表示书籍总数和必须进行的操作次数。
第二行包含一个长度为 的字符串
,由大写字母和小写字母组成,表示每本书的初始装帧类型。
输出格式
输出一个整数,表示恰好进行 次装帧转换操作后,书架上精装本的最大数量。
样例输入
1 3
A
样例输出
0
样例 | 解释说明 |
---|---|
样例1 | 初始有1本精装本,经过3次操作后:第1次变成平装本,第2次变成精装本,第3次又变成平装本,最终精装本数量为0 |
数据范围
- 字符串只包含大写和小写英文字母
题解
这道题的关键在于理解操作的本质和奇偶性的影响。
首先分析问题:我们要在恰好 次操作后最大化精装本数量。对于任意一本书,如果对它进行奇数次操作,它的装帧会改变;如果进行偶数次操作,装帧保持不变。
设初始时精装本数量为 ,平装本数量为
。假设我们对
本平装本各进行奇数次操作(它们变成精装本),对
本精装本各进行奇数次操作(它们变成平装本),剩余的操作可以配对进行偶数次操作,不影响最终状态。
约束条件:
,
,且
最终精装本数量为 ,为了最大化这个值,我们希望
尽可能大,
尽可能小。
分两种情况讨论:
情况1: 直接对
本平装本进行操作,令
,
,答案为
。
情况2: 先将所有平装本都转换为精装本(
),此时还剩
次操作。
- 如果
为偶数,可以全部用于配对操作,答案为
- 如果
为奇数,必须再将一本精装本转换为平装本,答案为
时间复杂度为 。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
n, k = map(int, input().split())
s = input()
# 统计初始精装本数量
up_cnt = sum(1 for c in s if c.isupper())
low_cnt = n - up_cnt
if k <= low_cnt:
# 直接转换k本平装本
ans = up_cnt + k
else:
# 先转换所有平装本,再考虑剩余操作
rem = k - low_cnt
ans = n - (rem % 2)
print(ans)
- Cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n, k;
cin >> n >> k;
string s;
cin >> s;
// 统计初始精装本数量
long long up = 0;
for (char c : s) {
if (c >= 'A' && c <= 'Z') up++;
}
long long low = n - up;
long long ans;
if (k <= low) {
// 直接转换k本平装本
ans = up + k;
} else {
// 先转换所有平装本,再考虑剩余操作
long long rem = k - low;
ans = n - (rem & 1);
}
cout << ans << endl;
return 0;
}
- Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long k = sc.nextLong();
String s = sc.next();
// 统计初始精装本数量
long upCnt = 0;
for (int i = 0; i < s.length(); i++) {
if (Character.isUpperCase(s.charAt(i))) {
upCnt++;
}
}
long lowCnt = n - upCnt;
long ans;
if (k <= lowCnt) {
// 直接转换k本平装本
ans = upCnt + k;
} else {
// 先转换所有平装本,再考虑剩余操作
long rem = k - lowCnt;
ans = n - (rem % 2);
}
System.out.println(ans);
sc.close();
}
}
02. 音符序列调整
问题描述
小兰是一名音乐编辑,她正在处理一段音乐的音符序列。这段音乐包含 个音符,音符的音高分别为
,且满足
(音高呈非严格递增)。
为了让音乐更有层次感,小兰希望通过一次特殊的"音高提升"操作来打破这种单调的递增关系。具体来说,她可以选择一个连续的音符区间 (
),然后对区间内的每个音符
(
),将其音高调整为
,其中
是一个固定的音高增量。
注意到这种操作的特点是:区间内靠前的音符会得到更大的音高提升。
小兰想知道,为了让调整后的音符序列存在某个位置 使得
(即打破单调递增),她需要选择的区间长度
的最小值是多少?如果无法通过一次操作达到目标,则输出
。
输入格式
每个测试文件包含多组测试数据。
第一行包含一个正整数 (
),表示测试数据组数。
对于每组测试数据:
- 第一行包含两个正整数
和
(
,
),分别表示音符数量和音高增量。
- 第二行包含
个正整数
(
),表示音符的初始音高。
保证所有测试数据中 。
输出格式
对于每组测试数据,输出一个整数,表示所需的最小区间长度;如果无法通过一次操作打破单调递增关系,输出 。
样例输入
2
4 2
1 2 3 3
3 1
2 6 8
样例输出
1
-1
样例 | 解释说明 |
---|---|
样例1 | 选择区间 |
样例2 | 无论如何操作都无法打破单调递增关系,因为相邻音符的音高差都不小于增量 |
数据范围
题解
这道题的关键在于理解操作的效果和寻找最优策略。
首先分析操作的本质:选择区间 后,区间内相邻音符的音高差会发生变化。具体来说,对于区间内的相邻音符
和
,操作后
会比
多增加
的音高。
要让 成立,有两种可能的情况:
和
都在操作区间内:此时
比
多增加
在区间末尾且
在区间外:此时
增加
而
不变
无论哪种情况,本质上都是让 相对于
增加了
的音高。
因此,要想打破原来的 关系,必须满足:
一旦存在这样的相邻位置,我们只需要选择长度为1的区间 即可:让
增加
而
保持不变,从而实现
。
如果所有相邻音符的音高差都不小于 ,那么无论如何操作,最多只能将差值减少
,仍然保持非严格递增关系,此时答案为
。
算法步骤:
- 遍历所有相邻的音符对
- 检查是否存在
- 如果存在,答案为1;否则答案为-1
时间复杂度为 ,总复杂度为
。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
t = int(input())
for _ in range(t):
n, m = map(int, input().split())
a = list(map(int, input().split()))
# 检查是否存在可以打破的位置
found = False
for i in range(n - 1):
if a[i + 1] - a[i] < m:
found = True
break
print(1 if found else -1)
- Cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
long long m;
cin >> n >> m;
vector<long long> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
// 检查是否存在可以打破的位置
bool found = false;
for (int i = 0; i < n - 1; i++) {
if (a[i + 1] - a[i] < m) {
found = true;
break;
}
}
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力