米哈游笔试 米哈游笔试题 0331
笔试时间:2024年03月31日
历史笔试传送门:2023秋招笔试合集
第一题
题目:米小游与—番赏2.0
本题目由抽崩坏三茶歇时刻—番赏真实事件改(乱)编!
一番赏初始有n个抽赏,有m个人排队购买,在队列最前面的人可以购买1个抽赏,买完之后这个人可以再次排队。
每一个抽赏都对应一个从'A'到'I'之间的大写字母,A赏比B赏稀有,B赏比C赏稀有,以此类推。买走最后一个抽赏的人将额外获赠一个last赏,为了简化,我们将last赏计为S赏,S赏比A赏稀有。
米小游知道一个只由大写字母组成的字符串s,表示购买第i个抽赏可以获得赏,她也知道排队购买抽赏的顺序数组a,表示购买i个抽赏的是第个人。米小游想知道每个人抽到了哪些赏,按稀有度排序,最稀有的排在最前面。(数据保证每个人至少购买了1个抽赏)。
输入描述
第—行输入两个整数n,m,表示抽赏个数、人数;
第二行输入一个长度为n的只由'A'到'I'之间的大写字母组成的字符串s;
第三行输入一个长度为n的数组a,表示排队购买抽赏的顺序数组。
输出描述
输出m行,每行输出一个字符串表示第i个人获得的抽赏,按稀有度顺序排序。
样例输入一
3 2
CAB
1 1 2
样例输出一
ACSB
第1个人购买了第1个抽赏,为C赏。第1个人购买了第2个抽赏,为A赏。
第2个人购买了第3个抽赏,为B赏,并获赠一个last赏,计为S赏。第1个人获得的抽赏为AC。(A赏比C赏稀有)
第1个人获得的抽赏为SB。(S赏比B赏稀有)
样例输入二
65
ABCDEA
1 2 3 4 5 1
样例输出二
SAA
B
C
D
E
参考题解
统计每个人得到的抽赏集合,再按照字典序排序即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; int main() { int n, m; cin >> n >> m; string s; cin >> s; vector<vector<char>> ans(n); for (int i = 0; i < n; ++i) { int a; cin >> a; ans[a - 1].push_back(s[i]); if (i == n - 1) { ans[a - 1].push_back('S'); } } for (int i = 0; i < n; ++i) { sort(ans[i].begin(), ans[i].end(), [&](auto a, auto b) { if (a == 'S') return true; if (b == 'S') return false; return a < b; }); for (char c : ans[i]) cout << c; cout << "\n"; } }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int m = scanner.nextInt(); String s = scanner.next(); List<List<Character>> ans = new ArrayList<>(); for (int i = 0; i < n; ++i) { int a = scanner.nextInt(); while (ans.size() < a) { ans.add(new ArrayList<>()); } ans.get(a - 1).add(s.charAt(i)); if (i == n - 1) { ans.get(a - 1).add('S'); } } for (int i = 0; i < n; ++i) { Collections.sort(ans.get(i), (a, b) -> { if (a == 'S') return 1; if (b == 'S') return -1; return Character.compare(a, b); }); for (char c : ans.get(i)) System.out.print(c); System.out.println(); } } }
Python:[此代码未进行大量数据的测试,仅供参考]
n, m = map(int, input().split()) s = input() ans = [[] for _ in range(n)] for i in range(n): a = int(input()) ans[a - 1].append(s[i]) if i == n - 1: ans[a - 1].append('S') for i in range(n): ans[i].sort(key=lambda x: x if x != 'S' else '', reverse=True) print(''.join(ans[i]))
第二题
题目:米小游的遗器
米小游有n个遗器,遗器共有m种类型,每个遗器有一个分数α和类型b。米小游最喜欢的角色是三月七,为了合成适合三月七的遗器,米小游准备分解掉不需要的遗器,但她需要保留k个遗器,且每种类型的遗器都至少要保留一个。米小游想知道她能保留的k个遗器的总分最高是多少。
输入描述
第一行输入三个整数n,m,k表示遗器个数、遗器类型、要保留的遗器个数。
接下来n行,每行输入两个整数表示遗器a,b,数据保证每种类型的遗器至少有1个。
输出描述
输出一个整数表示答案。
样例输入
4 2 3
1 1
1 2
2 1
2 2
样例输出
5
说明:
保留第2、3、4个遗器,或保留第1、3、4个遗器。
参考题解
使用最大堆排序,剩余的遗器中选择分数最大的几个
C++:[此代码未进行大量数据的测试,仅供参考]
#include <functional> #include <iostream> #include <string> #include <vector> #include <algorithm> #include <unordered_map> #include <queue> using namespace std; using ll = long long; using iter = vector<int>::iterator; using P = pair<iter, int>; int main() { int n, m, k; cin >> n >> m >> k; vector<vector<int>> arr(n); unordered_map<int, vector<int>> g; for (int i = 0; i < n; ++i) { int a, b; cin >> a >> b; g[b].push_back(a); } ll ans = 0, sz = k - g.size(); auto cmp = [](P& a, P& b){ return *a.first < *b.first; }; priority_queue<P, vector<P>, decltype(cmp)> pq(cmp); for (auto& [k, v] : g) { sort(v.begin(), v.end(), greater<>()); ans += v[0]; if (v.size() > 1) pq.push({v.begin() + 1, k}); } while (sz) { auto [it, k] = pq.top(); pq.pop(); ans += *it; it++; if (it != g[k].end()) pq.push({it, k}); --sz; } cout << ans; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { static class Pair { ListIterator<Integer> iter; int value; Pair(ListIterator<Integer> iter, int value) { this.iter = iter; this.value = value; } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int m = scanner.nextInt(); int k = scanner.nextInt(); ArrayList<ArrayList<Integer>> arr = new ArrayList<>(n); HashMap<Integer, ArrayList<Integer>> g = new HashMap<>(); for (int i = 0; i < n; ++i) { int a
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。