【秋招笔试】2025.08.09美团秋招研发岗机考改编
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线100+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
题目一:密码系统的统一编码规范
1️⃣:统计每个字母的大小写出现次数,选择代价最小的统一形式
2️⃣:使用贪心策略构造字典序最小的合法字符串
3️⃣:通过插入和删除操作实现最少步数的转换
难度:中等
这道题目考查对字符串处理和贪心算法的理解。关键在于为每个字母选择最优的大小写形式,然后通过巧妙的合并策略构造出字典序最小的结果。需要注意的是代价相等时优先选择大写字母,以及插入字符时的最优位置选择。
题目二:小柯的资源收集策略
1️⃣:设计动态规划状态,以探索次数模10作为关键维度
2️⃣:分析两种策略的收益差异,建立状态转移方程
3️⃣:使用滚动数组优化空间复杂度,处理大数据范围
难度:中等
这道题目是典型的动态规划问题,难点在于理解连击奖励机制和状态空间的设计。通过观察连击数模10的周期性特征,可以将状态空间压缩到常数级别,从而实现高效的解法。题目考查了对状态转移和空间优化的深入理解。
题目三:智能电网配线方案分析
1️⃣:理解问题的数学模型:随机完美匹配生成的2-正则图
2️⃣:运用组合数学推导期望和方差的计算公式
3️⃣:预处理逆元和前缀和,实现高效查询
难度:难
这道题目结合了概率论、组合数学和数论。需要深入理解随机匹配的性质,推导出环数的分布规律,并运用模逆元处理分数运算。通过预处理技术,将单次查询的复杂度优化到 O(1)。
01. 密码系统的统一编码规范
问题描述
本题在机考时允许用 ai 辅助答题
小基 正在开发一个新的密码系统,该系统要求所有密码必须符合"统一编码规范"。一个密码符合统一编码规范,当且仅当:
- 对于任意一种英文字母,该字母在密码中要么全部是大写形式,要么全部是小写形式(不能同时存在大写和小写)
- 英文字母表中的每个字母(不分大小写)都必须在密码中至少出现一次
现在给定一个长度为 、仅由大小写英文字母组成的密码字符串
。小基 需要通过最少的操作次数将其转换为符合统一编码规范的密码。她可以进行以下两种操作:
操作一:在字符串的任意位置(包括开头和结尾)插入一个字母(大写或小写) 操作二:删除字符串中的任意一个字符
小基 想知道通过最少次数的操作后,能够得到的字典序最小的符合统一编码规范的密码是什么。
输入格式
输入包含多组测试数据。第一行包含一个正整数 ,表示测试数据的组数。
对于每组测试数据:
- 第一行包含一个正整数
,表示原密码字符串的长度
- 第二行包含一个长度为
的字符串
,仅由大小写英文字母组成
输出格式
对于每组测试数据,输出一行,表示经过最少操作次数后能得到的字典序最小的符合统一编码规范的密码。
样例输入
5
26
abcdefGHljklmnopqrstuvwxyY
8
CAECGEHG
10
MZbMwEyYdl
20
DTLCOUegMDByFWUrPwBp
19
LKGkheSppLQSsAlmtll
样例输出
ZabcdefGHljklmnopqrstuywxY
BCADECFGEHGIJKLMNOPQRSTUVWXYZ
ACFGHJKLMNOPQRSTUVXZbMwEYdl
ADHIJKNQSTLCOUVXZеgMDByFUrPwB
BCDFGJNORUVWXYZkheSppQsAlmtll
数据范围
- 单个测试文件中所有测试数据的
之和不超过
样例 | 解释说明 |
---|---|
样例1 | 原字符串中缺少字母Z且y同时有大小写,删除小写y并在开头插入大写Z,得到统一编码规范的密码 |
样例2 | 原字符串只有大写字母,需要补全缺失的字母并保持大写形式 |
样例3 | 选择合适的大小写形式并补全缺失字母,确保字典序最小 |
样例4 | 处理复杂的大小写混合情况,通过最优策略得到规范密码 |
样例5 | 在保证规范的前提下,构造字典序最小的结果 |
题解
暂时没有通过✅的代码,以下思路仅作参考
这道题目的核心在于理解"统一编码规范"的含义,然后找到最优的大小写选择策略。
问题分析: 每种字母必须选择统一的大小写形式,且所有26个字母都要出现。对于每个字母,需要决定保留大写还是小写形式。
解题策略:
-
统计每个字母的大小写出现次数
- 用数组记录每个字母在原字符串中大写和小写的出现次数
-
为每个字母选择最优的大小写形式
- 保留大写的代价:需要删除所有小写 + 如果没有大写则需要插入1个大写
- 保留小写的代价:需要删除所有大写 + 如果没有小写则需要插入1个小写
- 选择代价更小的方案;如果代价相等,优先选择大写(ASCII码更小,字典序更优)
-
构造字典序最小的结果
- 从原字符串中保留符合选择方案的字符,按原顺序组成保留序列
- 将需要插入的缺失字母按ASCII码升序排列
- 使用贪心策略将缺失字母插入到最优位置:遍历保留序列,在每个位置前插入所有不大于当前字符的缺失字母
这个策略的正确性在于:总是优先放置ASCII码较小的字符,能够保证最终结果的字典序最小。
时间复杂度:,空间复杂度:
。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve():
n = int(input())
s = input()
# 统计每个字母的大小写出现次数
cnt_upper = [0] * 26 # 大写次数
cnt_lower = [0] * 26 # 小写次数
for ch in s:
if ch.islower():
cnt_lower[ord(ch) - ord('a')] += 1
else:
cnt_upper[ord(ch) - ord('A')] += 1
# 为每个字母选择保留大写还是小写
keep_upper = [False] * 26
need_insert = [] # 需要插入的字符
for i in range(26):
# 计算保留大写和小写的代价
cost_upper = cnt_lower[i] + (1 if cnt_upper[i] == 0 else 0)
cost_lower = cnt_upper[i] + (1 if cnt_lower[i] == 0 else 0)
if cost_upper < cost_lower or (cost_upper == cost_lower):
# 选择保留大写
keep_upper[i] = True
if cnt_upper[i] == 0:
need_insert.append(chr(ord('A') + i))
else:
# 选择保留小写
keep_upper[i] = False
if cnt_lower[i] == 0:
need_insert.append(chr(ord('a') + i))
# 按ASCII码排序需要插入的字符
need_insert.sort()
# 构建保留的字符序列
kept = []
for ch in s:
idx = ord(ch.lower()) - ord('a')
# 检查该字符是否符合选择的大小写方案
if (ch.isupper() and keep_upper[idx]) or (ch.islower() and not keep_upper[idx]):
kept.append(ch)
# 合并插入字符和保留字符,构造最终结果
result = []
insert_idx = 0
for ch in kept:
# 插入所有ASCII码不大于当前字符的缺失字符
while insert_idx < len(need_insert) and need_insert[insert_idx] <= ch:
result.append(need_insert[insert_idx])
insert_idx += 1
result.append(ch)
# 插入剩余的缺失字符
while insert_idx < len(need_insert):
result.append(need_insert[insert_idx])
insert_idx += 1
return ''.join(result)
T = int(input())
for _ in range(T):
print(solve())
- Cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
string s;
cin >> n >> s;
// 统计大小写字母出现次数
vector<int> upper_cnt(26, 0), lower_cnt(26, 0);
for (char c : s) {
if (islower(c)) {
lower_cnt[c - 'a']++;
} else {
upper_cnt[c - 'A']++;
}
}
// 决定每个字母保留的大小写形式
vector<bool> use_upper(26);
vector<char> missing;
for (int i = 0; i < 26; i++) {
int cost_u = lower_cnt[i] + (upper_cnt[i] == 0 ? 1 : 0);
int cost_l = upper_cnt[i] + (lower_cnt[i] == 0 ? 1 : 0);
if (cost_u <= cost_l) {
use_upper[i] = true;
if (upper_cnt[i] == 0) {
missing.push_back('A' + i);
}
} else {
use_upper[i] = false;
if (lower_cnt[i] == 0) {
missing.push_back('a' + i);
}
}
}
// 排序缺失字符
sort(missing.begin(), missing.end());
// 构建保留字符序列
string kept;
for (char c : s) {
int idx = tolower(c) - 'a';
bool is_upper = isupper(c);
if ((is_upper && use_upper[idx]) || (!is_upper && !use_upper[idx])) {
kept.push_back(c);
}
}
// 合并构造最终结果
string ans;
int pos = 0;
for (char c : kept) {
while (pos < missing.size() && missing[pos] <= c) {
ans.push_back(missing[pos]);
pos++;
}
ans.push_back(c);
}
while (pos < missing.size()) {
ans.push_back(missing[pos]);
pos++;
}
cout << ans << '\n';
}
return 0;
}
- Java
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
while (T-- > 0) {
int n = Integer.parseInt(br.readLine());
String s = br.readLine();
// 统计每个字母的出现次数
int[] upperCnt = new int[26];
int[] lowerCnt = new int[26];
for (char c : s.toCharArray()) {
if (Character.isLowerCase(c)) {
lowerCnt[c - 'a']++;
} else {
upperCnt[c - 'A']++;
}
}
// 选择每个字母的大小写形式
boolean[] useUpper = new boolean[26];
List<Character> missing = new ArrayList<>();
for (int i = 0; i < 26; i++) {
int costUpper = lowerCnt[i] + (upperCnt[i] == 0 ? 1 : 0);
int costLower = upperCnt[i] + (lowerCnt[i] == 0 ? 1 : 0);
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力