美团笔试 美团笔试题 0308
笔试时间:2025年03月08 春招实习
历史笔试传送门:2023秋招笔试合集
第一题
题目:小美的文本加密
小美有一个加密的字符串s,你无意之间得到了他的加密方式,尝试解开它吧!初始时,解密字符串t为空,除此之外,还有一个记录位移的整数p为0。依次对每一个i= 1,2,...,|s|进行以下操作(其中|s|代表字符串 s的长度):如果 s的第i个字符为数字x,则需要对p修改,具体地:若p=0,则将p置为x(即p>x);若p≠0,则将P中的数字全部向高位移动一位,随后将空出来的个位填上x(即p→ 10p+x);如果s的第i个字符不为数字,则需要先将字符串左移p 位 (即 t1t2···tptp+1···t|t|→ tp+1···t|t|t1t2···tp),随后将p重新置为0,再对t修改,具体地:若字符为R,则反转字符串t;字符不为R,则直接将这个字符添加到字符串t的结尾;请你直接输出解密完成后的字符串t。
输入描述
每个测试文件均包含多组测试数据。
第一行输入一个整数T(1≤T<=10)代表数据组数,每组测试数据描述如下
在一行上输入一个长度为|s|(1<=|s|<=10^3),且由大小写字母和数字混合构成的字符串 s代表小美的加密串。
输出描述
对于每一组测试数据,在一行上输出一个字符串,代表解密完成后的字符串。
样例输入
2
meRD2o
D0ame3
样例输出
Demo
Dame
参考题解
直接模拟即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取整行并忽略缓冲区中剩余内容
while(n--){
string s;
getline(cin, s);
string t = "";
long long p = 0;
for(char c : s){
if(isdigit(c)){
// 累加数字
p = p * 10 + (c - '0');
} else {
// 进行旋转
long long num = p;
if(t.size() > 1){
num = p % t.size(); // 只有长度大于 1 才需要取模
}
// 将 t 的前 num 部分旋转到后面
// C++ substr 超过范围不会报错,而是返回可获取到的最大子串
t = t.substr(num) + t.substr(0, num);
// 重置 p
p = 0;
// 根据字符 c 进行对应操作
if(c == 'R'){
// 反转
reverse(t.begin(), t.end());
} else {
// 将字符附加到末尾
t.push_back(c);
}
}
}
cout << t << "\n";
}
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine()); // 先读取行,再转换为整数
while(n-- > 0) {
String s = sc.nextLine();
StringBuilder t = new StringBuilder();
long p = 0;
for(char c : s.toCharArray()) {
if(Character.isDigit(c)) {
// 累加数字
p = p * 10 + (c - '0');
} else {
// 进行旋转
long num = p;
if(t.length() > 1) {
num = p % t.length(); // 只有长度大于 1 才需要取模
}
// 将 t 的前 num 部分旋转到后面
String rotated;
if(num < t.length()) {
rotated = t.substring((int)num) + t.substring(0, (int)num);
} else {
// num >= t.length() 的情况,旋转相当于不变
rotated = t.toString();
}
// 用旋转后的结果替换
t = new StringBuilder(rotated);
// 重置 p
p = 0;
// 根据字符 c 进行对应操作
if(c == 'R') {
// 反转
t.reverse();
} else {
// 将字符附加到末尾
t.append(c);
}
}
}
// 输出结果
System.out.println(t);
}
sc.close();
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
n = int(input()) for _ in range(n): s = input() t = "" p = 0 for c in s: if c.isdigit(): p = p*10+int(c) else : num = p if len(t) > 1: num = p%len(t) t = t[num:]+t[:num] p = 0 if c == 'R': t = t[::-1] else: t += c print(t)
第二题
题目:小美架炮
在无限大的棋盘中有n个炮,第个炮的坐标是(xi,yi)。已知每个炮的攻击方式是:先选一个攻击方向(上、下、左、右),该方向上看见的第一个棋子为"炮架",该炮可以通过炮架攻击到炮架后面的棋子(只能攻击到炮架后面的第一个)小美希望你求出每个炮第一次攻击能攻击到多少个炮。
输入描述
第一行输入一个正整数n,代表炮的数量。
接下来的n行,每行输入两个整数xiyi,代表每个炮所在的坐标。
1<=n<=10^5
-10^9<=xi,yi<=10^9
输出描述
输出n行,每行输出一个整数,代表第i个炮可以攻击到的炮的数量。
样例输入
6
0 0
0 1
0 2
1 0
2 0
3 0
样例输出
2
0
1
1
1
1
参考题解
用两个map分别记录某横坐标下的所有大炮,以及某纵坐标下的所有大炮,对每个对应的vector排序,然后遍历每个炮的位置,二分找到对应下标。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
map<int, vector<int>> mp1, mp2;
int n;
int x[100005], y[100005], ans[100005];
int main() {
cin>>n;
for(int i = 1; i<=n; i++) {
cin>>x[i]>>y[i];
mp1[x[i]].push_back(y[i]);
mp2[y[i]].push_back(x[i]);
}
for(auto it = mp1.begin(); it != mp1.end(); it++) {
int t = it->first;
sort(mp1[t].begin(), mp1[t].end());
}
for(auto it = mp2.begin(); it != mp2.end(); it++) {
int t = it->first;
sort(mp2[t].begin(), mp2[t].end());
}
for(int i = 1; i<=n; i++) {
int pos = lower_bound(mp1[x[i]].begin(), mp1[x[i]].end(),y[i])-mp1[x[i]].begin();
if (pos >= 2) ans[i]++;
if(mp1[x[i]].size()- pos > 2) ans[i]++;
pos = lower_bound(mp2[y[i]].begin(), mp2[y[i]].end(),x[i])-mp2[y[i]].begin();
if (pos >= 2) ans[i]++;
if(mp2[y[i]].size()- pos > 2) ans[i]++;
}
for(int i = 1; i<=n; i++) cout << ans[i] << endl;
}
// 64 位输出请用 printf("%lld")
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*;
import java.io.*;
public class Main {
// 辅助函数:实现 lower_bound,返回第一个不小于 key 的索引
public static int lowerBound(ArrayList<Integer> list, int key) {
int lo = 0, hi = list.size();
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (list.get(mid) < key) {
lo = mid + 1;
} else {
hi = mid;
}
}
return lo;
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
// 下标采用 0-indexed
int[] x = new int[n], y = new int[n], ans = new int[n];
// 使用 TreeMap 保证 key 有序
TreeMap<Integer, ArrayList<Integer>> mp1 = new TreeMap<>();
TreeMap<Integer, ArrayList<Integer>> mp2 = new TreeMap<>();
for (int i = 0; i < n; i++) {
x[i] = sc.nextInt();
y[i] = sc.nextInt();
// mp1: key -> list of y
if (!mp1.containsKey(x[i])) {
mp1.put(x[i], new ArrayList<Integer>());
}
mp1.get(x[i]).add(y[i]);
// mp2: key -> list of x
if (!mp2.containsKey(y[i])) {
mp2.put(y[i], new ArrayList<Integer>());
}
mp2.get(y[i]).add(x[i]);
}
// 对 mp1 中的每个 list 排序
for (Map.Entry<Integer, ArrayList<Integer>> entry : mp1.entrySet()) {
Collections.sort(entry.getValue());
}
// 对 mp2 中的每个 list 排序
for (Map.Entry<Integer, ArrayList<Integer>> entry : mp2.entrySet()) {
Collections.sort(entry.getValue());
}
for (int i = 0; i < n; i++) {
// 对应 mp1[x[i]] 的 lower_bound
ArrayList<Integer> list1 = mp1.get(x[i]);
int pos = lowerBound(list1, y[i]);
if (pos >= 2)
ans[i]++;
if (list1.size() - pos > 2)
an
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。
查看10道真题和解析
