【春招笔试】2025.04.19-米哈游春招笔试改编题
✅ 春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题(建议用时:90分钟/套)
- 对照解析查漏补缺
- 配套练习题库
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
春秋招合集 -> 互联网必备刷题宝典🔗
米哈游
题目一:神秘符文转化术
1️⃣:理解大小写字母的不同转化规则
2️⃣:使用数学公式直接计算k轮后的结果,避免模拟
难度:中等
这道题目的关键在于找出字母转化的规律,通过数学公式直接计算出经过k轮转化后的最终状态,避免了直接模拟k轮转化的高时间复杂度。
题目二:数据安全清理协议
1️⃣:使用数组记录每个位置被删除的轮次
2️⃣:通过二分查找确定最少需要删除的字符数
3️⃣:高效判断子串匹配情况
难度:中等
这道题目结合了字符串处理和二分查找算法,需要理解删除操作的特殊规则。关键在于预处理每个位置被删除的轮次,并通过二分搜索找到最小的删除次数。
题目三:魔法网格变换术
1️⃣:分析网格变换操作的性质
2️⃣:证明总魔力值的奇偶性不变
3️⃣:转化为组合数学问题求解
难度:中等偏难
这道题目需要对问题进行深入分析,发现关键的数学性质。通过证明网格总魔力值的奇偶性不会改变,以及变换操作可以实现任意排列,将问题转化为一个组合数学问题,极大地简化了求解过程。
01. 神秘符文转化术
问题描述
小基 是一位古代符文研究者,她正在研究一种特殊的符文转化法则。这种法则需要对一串符文进行多轮转化,以激活其中蕴含的魔力。转化的规则如下:
在第 轮转化中(
从
开始):
- 所有大写符文会向前转化一位(例如 '
' 变为 '
','
' 变为 '
',以此类推)
- 所有小写符文会向后转化
位(例如在第一轮,'
' 变为 '
';在第二轮,'
' 变为 '
',以此类推)
- 当符文转化超出范围时,将循环回到符文序列的起点或终点(例如 '
' 向前变为 '
','
' 向后变为 '
')
小基 需要你的帮助,计算一串符文经过 轮转化后的最终形态。
输入格式
第一行包含一个字符串 ,由大小写字母混合构成,表示初始符文序列。
第二行包含一个整数 ,表示需要进行的转化轮数。
输出格式
输出经过 轮转化后的符文序列。
样例输入
WhilE
2
样例输出
UkloC
数据范围
样例1 | 第一轮转化:"WhilE" 变为 "VijmD"(大写字母左移1位,小写字母右移1位) 第二轮转化:"VijmD" 变为 "UkloC"(大写字母左移1位,小写字母右移2位) |
- 字符串
仅包含大小写英文字母
题解
这道题目看起来需要我们模拟每一轮符文的转化过程,但如果直接模拟,对于较大的 值(高达
)会导致超时。因此,我们需要寻找规律,一次性计算出
轮转化后的结果。
仔细观察转化规则,我们可以发现:
-
对于大写字母:每轮都是向前(左)移动1位,所以
轮后,总共左移
位,即
位(因为字母表循环)。
-
对于小写字母:第
轮向后(右)移动
位,所以
轮后,总共右移
位,即
位。
实现思路:
- 计算大写字母的总左移量
- 计算小写字母的总右移量
- 遍历原字符串的每个字符,根据其是大写还是小写,应用相应的移位变换
时间复杂度:,其中
是字符串长度。这个解法只需要遍历一次字符串,对每个字符进行一次常数时间的操作。 空间复杂度:
,需要存储原字符串和结果字符串。
这个解法的关键在于找到了计算总移动量的数学公式,避免了直接模拟 轮转化的高时间复杂度。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 读取输入
s = input()
k = int(input())
# 计算大写字母总左移量(逆时针移动)
up_shift = k % 26
# 计算小写字母总右移量(顺时针移动)
lw_shift = (k * (k + 1) // 2) % 26
# 处理每个字符
result = ""
for c in s:
if 'A' <= c <= 'Z':
# 大写字母左移 up_shift 位
new_pos = (ord(c) - ord('A') - up_shift) % 26
result += chr(ord('A') + new_pos)
elif 'a' <= c <= 'z':
# 小写字母右移 lw_shift 位
new_pos = (ord(c) - ord('a') + lw_shift) % 26
result += chr(ord('a') + new_pos)
else:
result += c
print(result)
- Cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// 读取输入
string s;
long long k;
cin >> s >> k;
// 计算移位量
int ushift = k % 26; // 大写左移
long long temp = k * (k + 1) / 2;
int lshift = temp % 26; // 小写右移
// 处理每个字符
for (char& c : s) {
if ('A' <= c && c <= 'Z') {
// 大写字母左移
c = 'A' + ((c - 'A' - ushift + 26) % 26);
} else if ('a' <= c && c <= 'z') {
// 小写字母右移
c = 'a' + ((c - 'a' + lshift) % 26);
}
}
cout << s << endl;
return 0;
}
- Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取输入
String s = sc.nextLine();
long k = sc.nextLong();
// 计算移位量
int upMv = (int)(k % 26); // 大写字母左移量
long total = k * (k + 1) / 2;
int lwMv = (int)(total % 26); // 小写字母右移量
// 构建结果
StringBuilder res = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'A' && c <= 'Z') {
// 大写字母向左移动
char newChar = (char)('A' + ((c - 'A' - upMv + 26) % 26));
res.append(newChar);
} else if (c >= 'a' && c <= 'z') {
// 小写字母向右移动
char newChar = (char)('a' + ((c - 'a' + lwMv) % 26));
res.append(newChar);
} else {
res.append(c);
}
}
System.out.println(res.toString());
}
}
02. 数据安全清理协议
问题描述
小毛是一家数据安全公司的高级工程师。他正在设计一个数据清理协议,以确保敏感数据在传输过程中的安全性。公司有两个字符串 和
,根据安全规范,字符串
不允许作为
的子串存在。
为了执行清理操作,小毛需要按照预定的顺序删除 中的一些字符,直到
不再包含
作为子串。值得注意的是,删除一个字符后,系统不会自动将字符串合并,而是用一个空白字符替代被删除的字符。
小毛希望知道在保证安全的前提下,最少需要删除多少个字符。删除的顺序已经由系统生成,表示为一个排列 ,其中
表示第
次操作将删除
中的第
个字符。
输入格式
第一行包含两个整数 和
,表示字符串
和
的长度。
第二行包含一个长度为 的字符串
,仅包含小写字母。
第三行包含一个长度为 的字符串
,仅包含小写字母。
第四行包含 个整数
,表示删除操作的顺序。
输出格式
输出一个整数,表示最少需要删除的字符个数。
样例输入
5 2
ababa
ab
3 2 5 4 1
样例输出
2
数据范围
样例1 | 第一次删除 第二次删除 此时 |
题解
这道题目要求我们找出最少需要删除多少个字符,使得字符串 不再包含子串
。关键是注意删除字符时不会自动合并,而是用空白符替代。
解题思路:
-
首先,我们需要明确一点:按照给定的删除顺序,我们需要确定最少删除多少个字符才能使
不再包含
。
-
我们可以用二分查找来寻找答案。假设我们删除前
个字符,我们需要判断此时的字符串是否还包含子串
。
-
为了快速判断,我们预处理每个位置被删除的轮次
delTime[i]
。这样,当我们考虑删除前个字符时,只要
delTime[i] <= x
,就表示位置的字符已经被删除。
-
对于每个可能的子串起始位置
,我们检查
是否与
完全匹配,且这些位置的字符都没有被删除(即
delTime[i+j] > x
对于所有)。
-
如果找到了这样的子串,说明删除前
个字符后,
仍然包含
,需要继续删除;否则,我们可以停止删除。
时间复杂度分析:
- 预处理
delTime
数组需要时间
- 二分查找进行
次尝试
- 每次尝试需要
时间来检查所有长度为
的子串
- 总体时间复杂度为
空间复杂度: ,主要用于存储输入和
delTime
数组。
这个解法利用二分查找高效地找到答案,避免了逐个尝试从1到n的所有可能性。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 读取输入
n, m = map(int, input().split())
s = input()
t = input()
a = list(map(int, input().split()))
# 转换为0索引
a = [x-1 for x in a]
# 记录每个位置被删除的轮次
del_time = [0] * n
for i in range(n):
del_time[a[i]] = i + 1
# 二分查找
def check(x):
# 检查删除前x个字符后,s是否还包含t
for i in range(n - m + 1):
valid = True
for j in range(m):
# 如果当前位置已删除或字符不匹配
if del_time[i + j] <= x or s[i + j] != t[j]:
valid = False
break
if valid:
return False # 仍包含子串t
return True # 不再包含子串t
left, right =
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力