美团笔试 美团笔试题 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多种语言版本,持续更新中。