笔试 笔试 2024美团春季笔试真题 玦尘 2025-04-02 2025-04-04 本文为原创内容,转载请注明出处并附带原文链接。感谢您的尊重与支持!
1.小美的01矩阵 题目描述
小美拿到了一个n行m列的矩阵,她想知道该矩阵有多少个 2 * 2 的子矩形满足 1 和 0 的数量相等?
输入描述
第一行输入两个正整数n, m用空格隔开。
接下来的n行,每行输入一个长度为m的 01 串,用来表示矩阵。
2 <= n, m <= 100
输出描述
一个整数,代表 1 和 0 的数量相等的 2 * 2 的子矩形数量。
输入示例
2 3 110 010
输出示例
1
提示信息
一共有两个2 * 2的子矩形,只有一个是合法的。 时间限制:c/c++/go:1s;其他语言:3s。
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import java.util.Scanner;public class Main { public static void main (String[] args) { Scanner sc = new Scanner (System.in); String[] input = sc.nextLine().split(" " ); int m = Integer.parseInt(input[0 ]); int n = Integer.parseInt(input[1 ]); int [][] matrix = new int [m][n]; for (int i = 0 ; i < m; i++) { String line = sc.nextLine(); for (int j = 0 ; j < n; j++) { matrix[i][j] = line.charAt(j) - '0' ; } } int count = 0 ; for (int i = 0 ; i < m - 1 ; i++) { for (int j = 0 ; j < n - 1 ; j++) { int sum = matrix[i][j] + matrix[i][j + 1 ] + matrix[i + 1 ][j] + matrix[i + 1 ][j + 1 ]; if (sum == 2 ) { count++; } } } System.out.println(count); } }
2.小美的回文子串 题目描述
小美有一个长为 n的字符串s,她希望删除尽可能少的字符,使得字符串不含长度为偶数的回文子串。
她想知道她最少要删除几个字符,请你帮帮她吧。
输入描述
输入包含两行。
第一行一个正整数n(1 <= n <= 10^5),表示字符串s 的长度。
第二行一个长为n字符串s。
输出描述
输出包含一行一个整数,表示最少删除数量。
输入示例
5 aaabc
输出示例
2
提示信息
删除变为 abc即可,删除了2个字符。
时间限制:c/c++/go:1s;其他语言:3s。
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.util.Scanner;public class Main { public static void main (String[] args) { Scanner sc = new Scanner (System.in); int n = sc.nextInt(); sc.nextLine(); String str = sc.nextLine(); long ans = 0 ; for (int i = 1 ; i < n; i++) { if (str.charAt(i) == str.charAt(i - 1 )) { ans++; } } System.out.println(ans); } }
3.小美的元素交换 题目描述
小美拿到了一个排列,其中初始所有元素都是红色,但有一些元素被染成了白色。
小美每次操作可以选择交换任意两个红色元素的位置。她希望操作尽可能少的次数使得数组变成非降序,你能帮帮她吗?
排列是指:一个长度为n的数组,其中 1 到n每个元素恰好出现了一次。
输入描述
第一行输入一个正整数n,代表数组的长度。 第二行输入n个正整数ai,代表数组的元素。 第三行输入一个长度为n的字符串,代表数组元素的染色情况。第i个字符为’R’代表第i个元素被染成红色,为’W’代表初始的白色。
1 <= n <= 105 1 <= ai <= n
输出描述
如果无法完成排序,请输出 -1。否则输出一个整数,代表操作的最小次数。
输入示例
4 1 3 2 4 WRRW
输出示例
1
提示信息
第一次操作,交换 2 和 3,数组变成[1,2,3,4]。
时间限制:c/c++/go:1s;其他语言:3s。
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import java.util.*;public class Main { public static void main (String[] args) { Scanner sc = new Scanner (System.in); int n = sc.nextInt(); sc.nextLine(); int [] nums = new int [n]; Map<Integer, Integer> map = new HashMap <>(); for (int i = 0 ; i < n; i++) { int num = sc.nextInt(); nums[i] = num; } sc.nextLine(); String color = sc.nextLine(); for (int i = 0 ; i < n; i++) { map.put(nums[i], i); } int res = 0 ; for (int i = 0 ; i < n; i++) { if (nums[i] == i + 1 ) { continue ; } int pos = map.get(i + 1 ); if (color.charAt(i) == 'R' && color.charAt(pos) == 'R' ) { res++; int temp = nums[i]; nums[i] = nums[pos]; nums[pos] = temp; map.put(nums[pos], pos); map.put(nums[i], i); } else { System.out.println(-1 ); return ; } } System.out.println(res); } }
4.小美的字符串切割 题目描述
小美定义一个字符串的权值为:字符串长度乘以字符的种类数。例如,”arcaea”的权值为 6 * 4=24
现在小美拿到了一个字符串,她希望你将该字符串切割成若干个连续子串,使得每个子串的权值不小于k。请你求出最终最多可以切割出的子串数量。
请注意,由于字符串过长,给出的字符串将是以连续段长度形式给出,例如:aabbaaa 将描述为 a(2)b(2)a(3),aaaaaaaaaaaab 将描述为 a(12)b(1)。
注意:a(2)a(2)也是有效的数据。
输入描述
第一行输入一个两个正整数 n, k,代表原字符串长度和每个子串至少应取的权值。 第二行一个仅包含小写字母、数字和括号的字符串。长度不超过 10^6。 保证所有括号内的数字之和恰好等于n。给定的每个字母后面必然包含一个括号加数字。
1 <= k, n <= 10^18
输出描述
如果整个字符串的权值小于k,请直接输出 -1。
否则输出一个正整数,代表可以切割的最多子串数量。
输入示例
7 6 a(2)b(2)a(3)
输出示例
2
提示信息
该字符串表示为”aabbaaa”,切割成”aab”和”baaa”即可。
时间限制:c/c++/go:1s;其他语言:3s。
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import java.util.HashSet;import java.util.Scanner;import java.util.Set;public class Main { public static void main (String[] args) { Scanner sc = new Scanner (System.in); long n = sc.nextLong(); long k = sc.nextLong(); sc.nextLine(); String s1 = sc.nextLine(); int res = 0 ; Set<Character> set = new HashSet <>(); int cntchar = 0 ; int cntlen = 0 ; int i = 0 ; while (i < s1.length()) { char c = s1.charAt(i); i += 2 ; int sum = 0 ; while (s1.charAt(i) != ')' ) { sum = sum * 10 + s1.charAt(i) - '0' ; i++; } i++; for (int j = 0 ; j < sum; j++) { if (!set.contains(c)) { set.add(c); cntchar++; } cntlen++; if (cntlen * cntchar >= k) { res++; cntlen = 0 ; cntchar = 0 ; set.clear(); } } } System.out.println(res != 0 ? res : -1 ); } }
5.迷路的孩子 题目描述
有一棵有n个节点的树,小美在s节点,要去t节点。 但小美是经常迷路的孩子,她不知道该怎么走,因此她每次都会随机选择一条之前没有走过的边走,小美想知道她能到达 t 节点的概率是多少。 有多次询问,每次询问需要求出小美能到达t节点的概率对10^9+7取模后的结果。 如果最后答案为分数,则最简分式后的形式为 a/b ,其中a和b互质,那么输出整数 x 使得 b * x = a (mod 10^9+7) 且 0 <= x <= 10^9+7。可以证明这样的整数 x 是唯一的。
输入描述
第一行输入一个整数 n(1 <= n <= 210^5) 表示树节点个数。 接下来 n-1 行,每行输入两个整数 u, v(1 <= u, v <= n) 表示树上的边。 接下来一行,输入一个整数 q(1 <= q <= 2 10^5) 表示询问次数。 接下来 q 行,每行输入两个整数 s,t(1 <= s, t <= n) 表示询问。
输出描述
输出 q 行,每行输出一个整数表示概率。
输入示例
3 1 2 1 3 2 2 3 1 3
输出示例
1 500000004
提示信息
第1个询问:
小美有1的概率从节点2走到节点1,然后有1的概率从节点1走到节点3,因此有1的概率能到达节点3。1对1000000007取模后的结果为1。
第2个询问:
小美有1/2的概率从节点1走到节点2,有1/2的概率从节点1走到节点3,因此只有1/2的概率能到达节点3,1/2对1000000007取模后的结果为500000004。
时间限制:c/c++/go:2s;java:12s;其他语言:20s。
算法思路:LCA + 乘法逆元 + DFS 。太难了,直接放弃…
参考答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 import java.io.*;import java.util.*; public class Main { static final int MOD = 1_000_000_007 ; static final int MAX_LOG = 20 ; static int [][] fa; static int [] depth; static List<Integer>[] graph; static long [] path; static List<Pair>[] start, end; static long [] ans; static class Pair { int node, idx; Pair(int node, int idx) { this .node = node; this .idx = idx; } } public static void main (String[] args) throws IOException { BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); PrintWriter out = new PrintWriter (System.out); StringTokenizer st; int n = Integer.parseInt(br.readLine()); graph = new ArrayList [n]; for (int i = 0 ; i < n; i++) graph[i] = new ArrayList <>(); for (int i = 1 ; i < n; i++) { st = new StringTokenizer (br.readLine()); int u = Integer.parseInt(st.nextToken()) - 1 ; int v = Integer.parseInt(st.nextToken()) - 1 ; graph[u].add(v); graph[v].add(u); } fa = new int [n][MAX_LOG]; depth = new int [n]; dfs1(0 , 0 ); int m = Integer.parseInt(br.readLine()); start = new ArrayList [n]; end = new ArrayList [n]; for (int i = 0 ; i < n; i++) { start[i] = new ArrayList <>(); end[i] = new ArrayList <>(); } ans = new long [m]; Arrays.fill(ans, 1 ); for (int i = 0 ; i < m; i++) { st = new StringTokenizer (br.readLine()); int u = Integer.parseInt(st.nextToken()) - 1 ; int v = Integer.parseInt(st.nextToken()) - 1 ; int z = lca(u, v); if (u != z) { start[u].add(new Pair (z, i)); if (v != z) { end[v].add(new Pair (z, i)); ans[i] = modMul(qpow(graph[z].size() - 1 ), qpow(qpow(graph[z].size()))); } } else { end[v].add(new Pair (u, i)); } } path = new long [n]; dfs2(0 , 0 ); for (long x : ans) { out.println(x); } out.flush(); } static void dfs1 (int node, int parent) { depth[node] = depth[parent] + 1 ; fa[node][0 ] = parent; for (int i = 1 ; i < MAX_LOG; i++) { fa[node][i] = fa[fa[node][i - 1 ]][i - 1 ]; } for (int neighbor : graph[node]) { if (neighbor != parent) dfs1(neighbor, node); } } static int lca (int x, int y) { if (depth[x] < depth[y]) { int temp = x; x = y; y = temp; } for (int i = MAX_LOG - 1 ; i >= 0 ; i--) { if (depth[fa[x][i]] >= depth[y]) x = fa[x][i]; } if (x == y) return x; for (int i = MAX_LOG - 1 ; i >= 0 ; i--) { if (fa[x][i] != fa[y][i]) { x = fa[x][i]; y = fa[y][i]; } } return fa[x][0 ]; } static void dfs2 (int u, int parent) { for (Pair p : end[u]) { int x = p.node, y = p.idx; long temp = modMul(modMul(path[parent], qpow(path[x])), qpow(graph[x].size())); ans[y] = modMul(ans[y], temp); } if (u != 0 ) path[u] = modMul(path[parent], qpow(graph[u].size() - 1 )); else path[u] = qpow(graph[u].size()); long qu = qpow(graph[u].size()); for (Pair p : start[u]) { int x = p.node, y = p.idx; long temp = modMul(modMul(path[parent], qpow(path[x])), qu); ans[y] = modMul(ans[y], temp); } for (int neighbor : graph[u]) { if (neighbor != parent) dfs2(neighbor, u); } } static long qpow (long a) { return qpow(a, MOD - 2 ); } static long qpow (long a, long b) { long res = 1 ; while (b > 0 ) { if ((b & 1 ) == 1 ) res = res * a % MOD; a = a * a % MOD; b >>= 1 ; } return res; } static long modMul (long a, long b) { return (a * b) % MOD; } }