【春招改编笔试】2025.03.08-米哈游春招解析

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺
  • 配套练习题库

🧸 题面描述等均已深度改编,所有题面背景均为原创,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力

互联网必备刷题宝典🔗

alt

2025.03.08-米哈游

题目一:字符变换大师

1️⃣:字符分类处理 2️⃣:ASCII码操作与模运算 3️⃣:字符串遍历与构建

整体难度:简单

该题目要求对字符串中的每个字符进行特定规则的变换:大写字母变为下一个字母,小写字母变为上一个字母,数字加1,其他字符变为下划线。通过遍历字符串并根据字符类型应用相应的变换规则,可以高效地解决问题。时间复杂度O(n),其中n是字符串的长度。

题目二:双重翻转的奥秘

1️⃣:寻找回文子串 2️⃣:检查不重叠的回文对 3️⃣:验证翻转操作的有效性

整体难度:中等

该题目要求找到两个不重叠的区间,对它们分别执行翻转操作后,字符串保持不变。关键是寻找长度为2或3的回文子串,因为翻转回文子串后,字符串本身不会改变。通过枚举所有可能的回文子串对,可以找到满足条件的解。时间复杂度O(n²),其中n是字符串的长度。

题目三:字符串团队管理

1️⃣:计算字符串差异值 2️⃣:构建字符串关系图 3️⃣:寻找最大连通分量

整体难度:中等偏难

该题目涉及字符串之间的差异值计算和图论中的连通分量分析。通过计算任意两个字符串之间的差异值,构建一个无向图,然后使用深度优先搜索(DFS)或广度优先搜索(BFS)找到最大的连通分量,从而确定最少需要删除的字符串数量。时间复杂度O(n²m),其中n是字符串数量,m是字符串长度。

01. 字符变换大师

问题描述

小兰是一位密码学爱好者,她设计了一种特殊的字符变换规则,用于加密和解密信息。她有一个长度为 的字符串,需要对其中的每个字符按照以下规则进行变换:

  • 如果是大写字母,则将其替换为字母表中的下一个字母(Z 替换为 A)
  • 如果是小写字母,则将其替换为字母表中的上一个字母(a 替换为 z)
  • 如果是数字,则将其替换为该数字加 1 的结果(9 替换为 0)
  • 如果是其他字符(如空格、标点符号等),则将其替换为下划线"_"

小兰想请你帮她实现这个字符变换算法,将给定的字符串按照上述规则进行变换,并输出变换后的结果。

输入格式

第一行输入一个整数 ,表示字符串的长度。

第二行输入一个长度为 的字符串 ,由数字、大小写字母、空格及 这七个常见半角符号构成。保证字符串的首尾不为空格。

输出格式

在一行上输出一个字符串,表示按照规则变换后的字符串。

样例输入

12
Ab91!?.+-*/

样例输出

Ba02________

数据范围

  • 字符串 由数字、大小写字母、空格及 这七个常见半角符号构成
  • 保证字符串的首尾不为空格
样例 解释说明
样例1 原字符串"Ab91!?.+-*/"中:A变为B,b变为a,9变为0,1变为2,其余字符全部变为下划线

题解

这道题目要求我们对一个字符串中的每个字符按照特定规则进行变换。变换规则很直观:大写字母变为下一个字母,小写字母变为上一个字母,数字加1,其他字符变为下划线。

解决这个问题的关键是正确识别字符的类型,并应用相应的变换规则。我们可以使用ASCII码的特性来判断字符类型:

  • 大写字母的ASCII码范围是65-90(A-Z)
  • 小写字母的ASCII码范围是97-122(a-z)
  • 数字的ASCII码范围是48-57(0-9)

对于每种类型的字符,我们需要处理循环的情况:

  • 对于大写字母Z,下一个字母应该是A
  • 对于小写字母a,上一个字母应该是z
  • 对于数字9,加1后应该是0

这些循环可以通过模运算(%)来优雅地处理。例如,对于大写字母,我们可以使用(c - 'A' + 1) % 26 + 'A'来计算下一个字母。

算法的时间复杂度是O(n),其中n是字符串的长度,因为我们需要遍历字符串中的每个字符并进行变换。空间复杂度也是O(n),用于存储变换后的字符串。

这个问题是一个典型的字符处理问题,通过简单的条件判断和字符变换,我们可以高效地解决它。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

def transform_string(s):
    """
    根据规则变换字符串
    """
    result = []
    for char in s:
        # 处理大写字母
        if 'A' <= char <= 'Z':
            # 将大写字母变为下一个字母
            next_char = chr((ord(char) - ord('A') + 1) % 26 + ord('A'))
            result.append(next_char)
        # 处理小写字母
        elif 'a' <= char <= 'z':
            # 将小写字母变为上一个字母
            prev_char = chr((ord(char) - ord('a') - 1) % 26 + ord('a'))
            result.append(prev_char)
        # 处理数字
        elif '0' <= char <= '9':
            # 将数字加1
            next_digit = chr((ord(char) - ord('0') + 1) % 10 + ord('0'))
            result.append(next_digit)
        # 处理其他字符
        else:
            # 将其他字符变为下划线
            result.append('_')
    
    return ''.join(result)

# 主函数
n = int(input())
s = input()
print(transform_string(s))
  • Cpp
#include <iostream>
#include <string>
using namespace std;

string transform_string(const string& s) {
    // 存储变换后的字符串
    string result;
    result.reserve(s.length());
    
    for (char c : s) {
        // 处理大写字母
        if (c >= 'A' && c <= 'Z') {
            // 将大写字母变为下一个字母
            char next_char = (c - 'A' + 1) % 26 + 'A';
            result.push_back(next_char);
        }
        // 处理小写字母
        else if (c >= 'a' && c <= 'z') {
            // 将小写字母变为上一个字母
            char prev_char = (c - 'a' + 25) % 26 + 'a'; // +25 等同于 -1 再加26
            result.push_back(prev_char);
        }
        // 处理数字
        else if (c >= '0' && c <= '9') {
            // 将数字加1
            char next_digit = (c - '0' + 1) % 10 + '0';
            result.push_back(next_digit);
        }
        // 处理其他字符
        else {
            // 将其他字符变为下划线
            result.push_back('_');
        }
    }
    
    return result;
}

int main() {
    int n;
    string s;
    
    // 读取输入
    cin >> n;
    cin.ignore(); // 忽略换行符
    getline(cin, s);
    
    // 输出变换后的字符串
    cout << transform_string(s) << endl;
    
    return 0;
}
  • Java
import java.util.Scanner;

public class Main {
    public static String transformString(String s) {
        // 使用StringBuilder高效构建字符串
        StringBuilder result = new StringBuilder(s.length());
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            
            // 处理大写字母
            if (c >= 'A' && c <= 'Z') {
                // 将大写字母变为下一个字母
                char nextChar = (char)((c - 'A' + 1) % 26 + 'A');
                result.append(nextChar);
            }
            // 处理小写字母
            else if (c >= 'a' && c <= 'z') {
                // 将小写字母变为上一个字母
                char prevChar = (char)((c - 'a' + 25) % 26 + 'a'); // +25 等同于 -1 再加26
                result.append(prevChar);
            }
            // 处理数字
            else if (c >= '0' && c <= '9') {
                // 将数字加1
                char nextDigit = (char)((c - '0' + 1) % 10 + '0');
                result.append(nextDigit);
            }
            // 处理其他字符
            else {
                // 将其他字符变为下划线
                result.append('_');
            }
        }
        
        return result.toString();
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        int n = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符
        String s = scanner.nextLine();
        
        // 输出变换后的字符串
        System.out.println(transformString(s));
        
        scanner.close();
    }
}

02. 双重翻转的奥秘

问题描述

小基是一位字符串研究专家,她正在研究一种特殊的字符串翻转操作。对于一个字符串,翻转操作定义为将一个区间 内的字符顺序完全颠倒,即将原来的 变为

小基想知道,对于一个给定的字符串,是否存在两个不重叠的区间 (满足 ),使得先对区间 进行翻转操作,再对区间 进行翻转操作后,得到的字符串与原始字符串完全相同。

如果存在这样的两个区间,请输出"YES"并给出一组满足条件的 值;如果不存在,则输出"NO"。

输入格式

第一行一个整数 ,表示字符串长度。

第二行一个长度为 的字符串 ,保证输入仅由小写字母组成。

输出格式

若可以满足题意,第一行输出"YES",第二行输出 个整数,代表 ,以空格隔开,若有多组解,输出任意一个。

若不能,输出"NO"。

样例输入

4
abcd

样例输出

NO

样例输入

13
abbagggfkfggc

样例输出

YES
1 4 6 12

数据范围

  • 字符串 仅由小写字母组成
样例 解释说明
样例1 对于字符串"abcd",不存在满足条件的两个区间
样例2 对于字符串"abbagggfkfggc",可以先翻转区间[1,4]得到"abbaggfkfggc",再翻转区间[6,12]得到"abbagggfkfggc",与原字符串相同

题解

这道题目要求我们找到两个不重叠的区间,对它们分别进行翻转操作后,字符串保持不变。这个问题乍看起来很复杂,但实际上有一个关键的观察:如果一个区间是回文串,那么对它进行翻转操作后,这个区间的字符不会发生变化。

基于这个观察,我们可以推导出一个重要结论:要使两次翻转后字符串保持不变,必须满足以下条件之一:

  1. 两个区间都是回文串
  2. 两个区间互为镜像(即翻转第一个区间后得到的子串与第二个区间相同)

对于条件1,如果两个区间都是回文串,那么无论怎么翻转,这两个区间的字符都不会改变,整个字符串自然保持不变。

对于条件2,这种情况比较复杂,需要考虑两个区间的相对位置和长度。

为了简化问题,我们可以专注于寻找回文子串。特别是,我们可以寻找长度为2或3的回文子串,因为这些是最简单的回文形式:

  • 长度为2的回文:两个相同的字符,如"aa"
  • 长度为3的回文:首尾字符相同的三字符串,如"aba"

算法步骤如下:

  1. 遍历字符串,找出所有长度为2或3的回文子串
  2. 检查是否存在两个不重叠的回文子串
  3. 如果存在,输出"YES"和对应的区间;否则输出"NO"

这个算法的时间复杂度是O(n²),其中n是字符串的长度。在最坏情况下,我们需要检查O(n²)对回文子串。但实际上,回文子串的数量通常远小于n²,所以算法在实践中效率较高。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

def find_palindrome_pairs(s, n):
    """
    寻找字符串中所有长度为2或3的回文子串
    """
    palindromes = []
    
    # 寻找长度为2的回文
    for i in range(n-1):
        if s[i] == s[i+1]:
            palindromes.append((i+1, i+2))  # 转换为1-based索引
    
    # 寻找长度为3的回文
    for i in range(n-2):
        if s[i] == s[i+2]:
            palindromes.append((i+1, i+3))  # 转换为1-based索引
    
    return palindromes

def check_non_overlapping_pairs(palindromes):
    """
    检查是否存在两个不重叠的回文子串
    """
    for i in range(len(palindromes)):
        a, b = palindromes[i]
        for j in range(i+1, len(palindromes)):
            c, d = palindromes[j]
            if b < c:  # 确保区间不重叠
                return a, b, c, d
    
    return None

# 主函数
n = int(input())
s = input()

# 寻找所有长度为2或3的回文子串
palindromes = find_palindrome_pairs(s, n)

# 检查是否存在两个不重叠的回文子串
result = check_non_overlapping_pairs(palindromes)

if result:
    print("YES")
    print(*result)
else:
    print("NO")
  • Cpp
#include <iostream>
#include <vector>
#include <utility>
using namespace std;

vector<pair<int, int>> find_palindrome_pairs(const string& s, int n) {
    // 存储所有长度为2或3的回文子串
    vector<pair<int, int>> palindromes;
    
    // 寻找长度为2的回文
    for (int i = 0; i < n-1; ++i) {
        if (s[i] == s[i+1]) {
            // 转换为1-based索引
      

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

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

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

全部评论

相关推荐

03-30 10:58
已编辑
澳门科技大学 Web前端
笔试前基本搜不到什么题,也不知道复习什么,直接考。考完看了别人发的帖子,好像所有技术岗考的内容都一样。鼠鼠投的是前端(人事系统)的暑期实习。1.&nbsp;单选题内容包括C++,计网,操作系统(进程线程调度的问题),浏览器缓存(没考前端的内容,觉得确实是所有技术岗位统考)2.&nbsp;多选题内容包括C++,计网,操作系统,数据结构(C++是真的多,我是一点也不会,没学,直接凉了,操作系统的那些选择也好多不会)3.&nbsp;代码题(1)&nbsp;给一个数组,定义一个“区间”=&nbsp;[1,&nbsp;i],在这个“区间”的对应凸区间&nbsp;=&nbsp;[min{a1,...&nbsp;ai},&nbsp;max{a1,&nbsp;...&nbsp;ai}]&nbsp;中,找出不属于该凸区间的最小非负数。(理解题意就得看好一会,头次看想错了,重写花了点时间,我直接按求区间-&gt;遍历区间求凸区间-&gt;获得结果,这种暴力写法写,不出意外超时,觉得可以用动态规划写,但没想出来)&#39;&#39;&#39;jslet&nbsp;arr&nbsp;=&nbsp;[1,&nbsp;0,&nbsp;4,&nbsp;5,&nbsp;1]let&nbsp;result&nbsp;=&nbsp;[]let&nbsp;min&nbsp;=&nbsp;Number.MAX_VALUE,&nbsp;max&nbsp;=&nbsp;0for(let&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;arr.length;&nbsp;i++)&nbsp;{&nbsp;&nbsp;//&nbsp;维护最大值和最小值就好,别再去求区间,遍历&nbsp;&nbsp;min&nbsp;=&nbsp;Math.min(min,&nbsp;arr[i])&nbsp;&nbsp;max&nbsp;=&nbsp;Math.max(max,&nbsp;arr[i])&nbsp;&nbsp;if(min&nbsp;&gt;&nbsp;0)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;result.push(0)&nbsp;&nbsp;}else&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;result.push(max+1)&nbsp;&nbsp;}}console.log(result)&#39;&#39;&#39;(2)&nbsp;给一个二进制序列,如:&amp;amp;amp;quot;001100&amp;amp;amp;quot;,然后把11往后移1位,...,最后形成一个方阵,如:001100000110000011100001110000011000求这个方阵中,由0组成的最大矩形或三角形的面积(没思路直接过)&#39;&#39;&#39;jslet&nbsp;s&nbsp;=&nbsp;&#39;001110&#39;/**&nbsp;*&nbsp;别傻傻去生成矩阵,直接求连续的0,再从1累加得到面积,如果全0则直接求正方形面积&nbsp;*&nbsp;&nbsp;*&nbsp;001110&nbsp;*&nbsp;000111&nbsp;*&nbsp;100011&nbsp;*&nbsp;110001&nbsp;*&nbsp;111000&nbsp;*&nbsp;011100&nbsp;*/let&nbsp;isSquare&nbsp;=&nbsp;truefor(const&nbsp;i&nbsp;of&nbsp;s)&nbsp;{&nbsp;&nbsp;if(i&nbsp;!==&nbsp;&#39;0&#39;)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;isSquare&nbsp;=&nbsp;false&nbsp;&nbsp;&nbsp;&nbsp;break&nbsp;&nbsp;}}if(isSquare)&nbsp;{&nbsp;&nbsp;console.log(s.length&nbsp;*&nbsp;s.length)}let&nbsp;zeroNum&nbsp;=&nbsp;s[0]&nbsp;===&nbsp;&#39;0&#39;&nbsp;?&nbsp;1&nbsp;:&nbsp;0let&nbsp;max&nbsp;=&nbsp;0let&nbsp;ss&nbsp;=&nbsp;s&nbsp;+&nbsp;sfor(let&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;&nbsp;ss.length;&nbsp;i++)&nbsp;{&nbsp;&nbsp;if(ss[i]&nbsp;===&nbsp;&#39;0&#39;&nbsp;&amp;amp;&amp;amp;&nbsp;ss[i&nbsp;-&nbsp;1]&nbsp;===&nbsp;&#39;1&#39;)&nbsp;zeroNum&nbsp;=&nbsp;1&nbsp;&nbsp;if(ss[i]&nbsp;===&nbsp;&#39;0&#39;&nbsp;&amp;amp;&amp;amp;&nbsp;ss[i&nbsp;-&nbsp;1]&nbsp;===&nbsp;&#39;0&#39;)&nbsp;zeroNum++&nbsp;&nbsp;max&nbsp;=&nbsp;Math.max(max,&nbsp;zeroNum)}console.log((1&nbsp;+&nbsp;max)&nbsp;*&nbsp;max&nbsp;/&nbsp;2)&#39;&#39;&#39;(3)&nbsp;给一个数组,一个查询次数n,和n个输入的目标值,求这个数组中任意2个不同的数,他们的乘积等于对应的目标值,输出是n对下标(找不到[-1,-1])。(也是直接暴力解法,过了20%,可以再进行剪枝,但还是没过)考完才发现可以用两数之和哈希表的操作&#39;&#39;&#39;jslet&nbsp;arr&nbsp;=&nbsp;[2,3,6,7,3,7,4]let&nbsp;target&nbsp;=&nbsp;6let&nbsp;map&nbsp;=&nbsp;new&nbsp;Map()let&nbsp;result&nbsp;=&nbsp;[]for&nbsp;(let&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;arr.length;&nbsp;i++)&nbsp;{&nbsp;&nbsp;if(arr[i]&nbsp;&gt;&nbsp;target)&nbsp;continue&nbsp;&nbsp;if&nbsp;(map.has(target&nbsp;/&nbsp;arr[i]))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;[i,&nbsp;map.get(target&nbsp;/&nbsp;arr[i])]&nbsp;&nbsp;}&nbsp;&nbsp;map.set(arr[i],&nbsp;i)}console.log(result)&#39;&#39;&#39;总结:太难了,又是一轮游,下去再沉淀沉淀。之前看过米哈游秋招的笔试,好像是21年还是22年的,手写题都没这么难,都a出来的,现在tm是越来越难,也可能是一紧张脑子乱了(好了不说了,主要原因是自己菜)再做了一遍,确实觉得没有考试那时感觉难,最后一题在想去重+根号n,去重的话,索引不会发生变化吗。(看看有无佬过了这一道)#笔试##米哈游##暑期实习##前端##前端实习#
查看5道真题和解析 投递米哈游等公司7个岗位 笔试
点赞 评论 收藏
分享
评论
5
6
分享

创作者周榜

更多
牛客网
牛客企业服务