【春招笔试】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. 对于大写字母:每轮都是向前(左)移动1位,所以 轮后,总共左移 位,即 位(因为字母表循环)。

  2. 对于小写字母:第 轮向后(右)移动 位,所以 轮后,总共右移 位,即 位。

实现思路:

  1. 计算大写字母的总左移量
  2. 计算小写字母的总右移量
  3. 遍历原字符串的每个字符,根据其是大写还是小写,应用相应的移位变换

时间复杂度:,其中 是字符串长度。这个解法只需要遍历一次字符串,对每个字符进行一次常数时间的操作。 空间复杂度:,需要存储原字符串和结果字符串。

这个解法的关键在于找到了计算总移动量的数学公式,避免了直接模拟 轮转化的高时间复杂度。

参考代码

  • 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 第一次删除 变为 "ab_ba"(下划线表示被删除的位置)
第二次删除 变为 "a__ba"
此时 不再包含子串 "ab",因此最少需要删除2个字符

题解

这道题目要求我们找出最少需要删除多少个字符,使得字符串 不再包含子串 。关键是注意删除字符时不会自动合并,而是用空白符替代。

解题思路:

  1. 首先,我们需要明确一点:按照给定的删除顺序,我们需要确定最少删除多少个字符才能使 不再包含

  2. 我们可以用二分查找来寻找答案。假设我们删除前 个字符,我们需要判断此时的字符串是否还包含子串

  3. 为了快速判断,我们预处理每个位置被删除的轮次 delTime[i]。这样,当我们考虑删除前 个字符时,只要 delTime[i] <= x,就表示位置 的字符已经被删除。

  4. 对于每个可能的子串起始位置 ,我们检查 是否与 完全匹配,且这些位置的字符都没有被删除(即 delTime[i+j] > x 对于所有 )。

  5. 如果找到了这样的子串,说明删除前 个字符后, 仍然包含 ,需要继续删除;否则,我们可以停止删除。

时间复杂度分析:

  • 预处理 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%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务