米哈游笔试 米哈游笔试题 0310
笔试时间:2024年03月10日
历史笔试传送门:2023秋招笔试合集
第一题
题目:米小游和蹦蹦史莱姆
地图上有 n 个格子排成一排,最左边的格子为1,最右边的格子为n。第0 秒时,每个格子都有一只史莱姆。第i 只史莱姆的跳跃方向用数组a 表示。ai=0 表示史莱姆跳跃的方向是往左。若第 i 秒史莱姆位于格子 x,那么第i+1 秒史莱姆会跳到格子x-1 。如果当前史莱姆在格子1,则下一秒史莱姆将跳出地图。ai=1 表示史莱姆跳跃的方向是往右。若第 i 秒史莱姆位于格子x,那么第 i+1 秒史莱姆会跳到格子x+1 。如果当前史莱姆在格子 n,则下一秒史莱姆将跳出地图。米小游想知道第 1-n 秒,地图上有多少个格子没有史莱姆。
输入描述
第一行包含一个整数n,n∈[1,3000],表示地图上的格子数量。
第二行包含n 个整数ai,ai∈[0,1],表示每只史莱姆的跳跃方向。
输出描述
输出包含一行n 个整数,用空格隔开,第i 个数表示第i 秒没有史莱姆的格子数量。
样例输入
3
1 0 1
样例输出
1 2 3
说明:史莱姆1-3 的跳跃方向分别为,往右,往左,往右。第 1 秒,史莱姆1 跳到格子 2,史莱姆2 跳到格子1,史莱姆3 跳出地图,格子3 没有史莱姆。第 2 秒,史莱姆 1 跳到格子3,史莱姆 2 跳出地图,格子 1,2 没有史莱姆。第 3 秒,史莱姆1 跳出地图,格子1,2,3 没有史莱姆。
参考题解
直接模拟即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream> #include <vector> using namespace std; string optimize_solution(int n, vector<int>& dirs) { vector<int> ans(n, 1); vector<vector<int>> positions(n, vector<int>(2, 0)); for (int i = 0; i < n; ++i) { positions[i][dirs[i]]++; } vector<int> res(n, 0); for (int i = 0; i < n; ++i) { vector<vector<int>> new_positions(n, vector<int>(2, 0)); for (int k = 0; k < n; ++k) { int l = positions[k][0]; int r = positions[k][1]; ans[k] -= (l + r); if (k - 1 >= 0) { ans[k - 1] += l; } if (k + 1 < n) { ans[k + 1] += r; } if (k - 1 >= 0) { new_positions[k - 1][0] += l; } if (k + 1 < n) { new_positions[k + 1][1] += r; } } positions = new_positions; res[i] = count(ans.begin(), ans.end(), 0); } string result; for (int num : res) { result += to_string(num) + " "; } return result; } int main() { int n; cin >> n; vector<int> dirs(n); for (int i = 0; i < n; ++i) { cin >> dirs[i]; } string result = optimize_solution(n, dirs); cout << result << endl; return 0; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static String optimizeSolution(int n, int[] dirs) { int[] ans = new int[n]; Arrays.fill(ans, 1); int[][] positions = new int[n][2]; for (int i = 0; i < n; i++) { positions[i][dirs[i]]++; } int[] res = new int[n]; for (int i = 0; i < n; i++) { int[][] newPositions = new int[n][2]; for (int k = 0; k < n; k++) { int l = positions[k][0]; int r = positions[k][1]; ans[k] -= (l + r); if (k - 1 >= 0) { ans[k - 1] += l; } if (k + 1 < n) { ans[k + 1] += r; } if (k - 1 >= 0) { newPositions[k - 1][0] += l; } if (k + 1 < n) { newPositions[k + 1][1] += r; } } positions = newPositions; res[i] = countZeros(ans); } StringBuilder result = new StringBuilder(); for (int num : res) { result.append(num).append(" "); } return result.toString(); } public static int countZeros(int[] array) { int count = 0; for (int num : array) { if (num == 0) { count++; } } return count; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] dirs = new int[n]; for (int i = 0; i < n; i++) { dirs[i] = scanner.nextInt(); } String result = optimizeSolution(n, dirs); System.out.println(result); } }
Python:[此代码未进行大量数据的测试,仅供参考]
from collections import defaultdict def optimize_solution(n, dirs): ans = [1]*n dic = {i: [0, 0] for i in range(n)} for i, d in enumerate(dirs): dic[i][d] += 1 res = [0]*n for i in range(n): new_dic = {i: [0, 0] for i in range(n)} for k, v in dic.items(): l, r = v ans[k] -= l+r if k-1 >= 0: ans[k-1] += l if k+1 < n: ans[k+1] += r if k-1 >= 0: new_dic[k-1][0] += l if k+1 < n: new_dic[k+1][1] += r dic = new_dic res[i] = ans.count(0) return ' '.join(map(str, res)) if __name__ == "__main__": n = int(input()) dirs = [int(c) for c in input().split()] result = optimize_solution(n, dirs) print(result)
第二题
题目:米小游与一番赏
本题目由抽崩坏三茶歇时刻一番赏真实事件改(乱)编!一番赏初始有 n 个抽赏,大家需要排队购买,只有在队列最前面的人可以选择购买或者不购买,所有人随时都可以离开队列,离开队列后也可以随时加入队列。米小游陪着她的好朋友莫娜来买一番赏,她时不时会看一眼队列中有多少人。也就是说,共有 4 种事件:
1 s:名字为 s 的人加入队列的结尾(保证图片不在队列中)。
2 s:名字为s 的人离开队列(保证 s 在队列中,但不一定在队列最前面)。
3 x:队列最前面的人购买了x 个抽赏(保证在抽赏个数大于 0 时,当前至少有x 个抽赏)。
4 :米小游查看队列人数。
还有一个特殊规则:当抽赏个数小于等于m 时,处于队列最前面的人一定会把剩余的所有抽赏全部买走。当抽赏全部被买走后,队列会立即清空,后续的所有事件都将失效。
米小游想知道,她每次查看队列人数时,队列中有多少人。以及最后抽赏全部卖完或者所有事件结束后,每个参与过排队的人各买了多少个抽赏?(按名字字典序升序输出)
输入描述
第一行输入三个整数 n,m (1<=m<=n<=10^9),q(1<=q<=2*10^5 表示抽赏个数、特殊规则限制、事件个数。
接下来q 行,首先输入一个整数 op(1<=op<=4) 表示事件类型:
若事件类型为 1 或 2,则再输入一个长度不超过 10 的只由大小写字母组成的字符串s 表示名字;
若事件类型为 3,则再输入一个整数x 表示购买的抽赏个数;
若事件类型为 4,则不再输入。
输出描述
对于每一个类型为 4 的事件,输出一行,包含一个整数表示队列中的人数。
最后每一行按字典序升序输出每一个参与过排队的人的名字和购买的抽赏个数(用一个空格隔开)。
样例输入一
70 20 8
1 Mona
1 Kaveh
4
2 Mona
1 Mona
2 Kaveh
4
1 Kaveh
样例输出一
2
1
Kaveh 0
Mona 0
说明:初始时队列为空。
第1个事件:Mona加入队列,队列为:["Mona"]。
第2个事件:Kaveh加入队列,队列为:["Mona","Kaveh"]。
第3个事件:查看队列人数,队列为:["Mona","Kaveh"],共有2人。
第4个事件:Mona离开队列,队列为:["Kaveh"]。
第5个事件:Mona加入队列,队列为:["Kaveh","Mona"]。
第6个事件:Kaveh离开队列,队列为:["Mona"]。
第7个事件:查看队列人数,队列为:["Mona"],共有1人。
第8个事件:Kaveh加入队列,队列为:["Mona","Kaveh"]。
Kaveh共购买了0个抽赏。
Mona
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。