【美团笔试题汇总】2024-04-13-美团春秋招笔试题-三语言题解(CPP/Python/Java)

2024-04-14 03:04

本文主要是介绍【美团笔试题汇总】2024-04-13-美团春秋招笔试题-三语言题解(CPP/Python/Java),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员

✨ 本系列打算持续跟新美团近期的春秋招笔试题汇总~

💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导

👏 感谢大家的订阅➕ 和 喜欢💗

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新。

文章目录

    • 🍓 01.K小姐的好子矩阵
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
      • 题解
      • 参考代码
    • 🍇 02.卢小姐的魔法数组
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
      • 题解
      • 参考代码
    • 🥥 03.A先生的红黑树
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
      • 题解
      • 参考代码
    • 🧀 04.LYA的因子数量查询
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
      • 题解
      • 参考代码
    • 🍅 05.LYA的字符串子序列集合
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
      • 题解
      • 参考代码
    • 写在最后
    • 📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新。

🍓 01.K小姐的好子矩阵

问题描述

K小姐拿到了一个 n n n m m m 列的矩阵,她想知道这个矩阵中有多少个 2 × 2 2 \times 2 2×2 的子矩阵是"好子矩阵"。一个子矩阵是"好子矩阵",当且仅当这个 2 × 2 2 \times 2 2×2 的子矩阵中的所有元素都相同。

输入格式

第一行包含两个正整数 n n n m m m,表示矩阵的行数和列数。

接下来的 n n n 行,每行包含 m m m 个正整数,表示这个矩阵。

输出格式

输出一个整数,表示 2 × 2 2 \times 2 2×2 好子矩阵的数量。

样例输入

3 3
1 2 1
1 1 1
1 1 3

样例输出

1

数据范围

1 ≤ n , m ≤ 100 1 \leq n, m \leq 100 1n,m100
1 ≤ a i , j ≤ 1 0 9 1 \leq a_{i,j} \leq 10^9 1ai,j109

题解

我们可以枚举矩阵中的每个 2 × 2 2 \times 2 2×2 的子矩阵,判断其是否为好子矩阵。具体做法如下:

  1. 枚举子矩阵的左上角位置 ( i , j ) (i, j) (i,j),其中 1 ≤ i ≤ n − 1 1 \leq i \leq n-1 1in1 1 ≤ j ≤ m − 1 1 \leq j \leq m-1 1jm1

  2. 对于每个 ( i , j ) (i, j) (i,j),判断以其为左上角的 2 × 2 2 \times 2 2×2 子矩阵是否为好子矩阵,即判断 a i , j a_{i,j} ai,j a i , j + 1 a_{i,j+1} ai,j+1 a i + 1 , j a_{i+1,j} ai+1,j a i + 1 , j + 1 a_{i+1,j+1} ai+1,j+1 是否都相等。

  3. 如果是好子矩阵,将答案加 1 1 1

  4. 枚举完所有的 ( i , j ) (i, j) (i,j) 后,即可得到好子矩阵的数量。

时间复杂度 O ( n m ) O(nm) O(nm),空间复杂度 O ( 1 ) O(1) O(1)

参考代码

  • Python
n, m = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(n)]ans = 0
for i in range(n - 1):for j in range(m - 1):if matrix[i][j] == matrix[i][j + 1] == matrix[i + 1][j] == matrix[i + 1][j + 1]:ans += 1print(ans)
  • Java
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[][] matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt();}}int ans = 0;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < m - 1; j++) {if (matrix[i][j] == matrix[i][j + 1] && matrix[i][j] == matrix[i + 1][j] &&matrix[i][j] == matrix[i + 1][j + 1]) {ans++;}}}System.out.println(ans);}
}
  • Cpp
#include <iostream>
using namespace std;const int N = 110;
int matrix[N][N];int main() {int n, m;cin >> n >> m;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> matrix[i][j];}}int ans = 0;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < m - 1; j++) {if (matrix[i][j] == matrix[i][j + 1] && matrix[i][j] == matrix[i + 1][j] &&matrix[i][j] == matrix[i + 1][j + 1]) {ans++;}}}cout << ans << endl;return 0;
}

🍇 02.卢小姐的魔法数组

问题描述

卢小姐有一个长度为 n n n 的整数数组。她可以对数组进行最多 k k k 次操作,每次操作可以选择数组中的任意一个元素,将其加 1 1 1 或减 1 1 1。卢小姐希望经过这些操作后,数组中元素为 0 0 0 的数量尽可能多。你能帮助她计算出最多能有多少个元素变成 0 0 0 吗?

输入格式

第一行包含两个正整数 n n n k k k,分别表示数组的长度和最多的操作次数。

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an,表示初始的数组。

输出格式

输出一个整数,表示经过最多 k k k 次操作后,数组中元素为 0 0 0 的最大数量。

样例输入

4 5
-2 3 -2 9

样例输出

2

数据范围

1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105
1 ≤ k ≤ 1 0 14 1 \leq k \leq 10^{14} 1k1014
− 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \leq a_i \leq 10^9 109ai109

题解

可以先将数组中的元素全部转换为绝对值,然后对数组进行排序。接着从小到大遍历数组,对于每个元素,如果 k k k 减去当前元素的值大于等于 0 0 0,就将 k k k 减去当前元素的值,并将答案加 1 1 1。如果 k k k 的值已经小于当前元素,说明无法继续转换了,直接退出循环即可。

最终的答案即为数组中可以变成 0 0 0 的元素的最大数量。

时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),空间复杂度为 O ( n ) O(n) O(n)

参考代码

  • Python
n, k = map(int, input().split())
arr = list(map(int, input().split()))
arr = [abs(x) for x in arr]
arr.sort()count = 0
for x in arr:if k >= x:k -= xcount += 1else:breakprint(count)
  • Java
import java.util.Arrays;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();long k = sc.nextLong();long[] arr = new long[n];for (int i = 0; i < n; i++) {arr[i] = Math.abs(sc.nextLong());}Arrays.sort(arr);int count = 0;for (long x : arr) {if (k >= x) {k -= x;count++;} else {break;}}System.out.println(count);}
}
  • Cpp
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;const int N = 100010;
long long arr[N];int main() {int n;long long k;cin >> n >> k;for (int i = 0; i < n; i++) {cin >> arr[i];arr[i] = abs(arr[i]);}sort(arr, arr + n);int count = 0;for (int i = 0; i < n; i++) {if (k >= arr[i]) {k -= arr[i];count++;} else {break;}}cout << count << endl;return 0;
}

🥥 03.A先生的红黑树

问题描述

A先生有一棵 n n n 个节点的树,根节点编号为 1 1 1。树上的每个节点都被染成了红色或黑色。A先生想知道,有多少个节点满足以该节点为根的子树中同时包含红色节点和黑色节点。

输入格式

第一行包含一个正整数 n n n,表示树的节点数。

第二行包含一个长度为 n n n 的字符串 s s s,其中 s i s_i si 表示编号为 i i i 的节点的颜色。如果 s i s_i siB,则表示该节点为黑色;如果 s i s_i siR,则表示该节点为红色。

接下来 n − 1 n-1 n1 行,每行包含两个正整数 u u u v v v,表示节点 u u u 和节点 v v v 之间有一条边。

输出格式

输出一个整数,表示满足条件的节点个数。

样例输入

3
BRB
1 2
2 3

样例输出

2

数据范围

1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105

题解

可以使用深度优先搜索(DFS)来解决这个问题。对于每个节点,维护一个长度为 2 2 2 的数组 t t t,其中 t t t 表示以该节点为根的子树中是否包含黑色节点, t t t 表示以该节点为根的子树中是否包含红色节点。

在 DFS 过程中,首先根据当前节点的颜色更新 t t t 数组。然后递归地处理当前节点的每个子节点,并将子节点的 t t t 数组与当前节点的 t t t 数组进行按位或操作,更新当前节点的 t t t 数组。

最后,如果当前节点的 t t t 数组中 t t t t t t 都为 1 1 1,说明以该节点为根的子树中同时包含红色节点和黑色节点,将答案加 1 1 1

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)

参考代码

  • Cpp
#include <bits/stdc++.h>
using namespace std;vector<vector<int>> g;
string s;
int res = 0;vector<int> dfs(int u, int pre) {vector<int> t(2);if (s[u - 1] == 'B')t[0] = 1;elset[1] = 1;for (int v : g[u]) {if (v != pre) {vector<int> child = dfs(v, u);t[0] |= child[0];t[1] |= child[1];}}if (t[0] && t[1])res++;return t;
}int main() {int n;cin >> n;cin >> s;g.resize(n + 1);for (int i = 0; i < n - 1; i++) {int u, v;cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}dfs(1, 0);cout << res << endl;return 0;
}
  • Python
n = int(input())
s = input()g = [[] for _ in range(n + 1)]
for _ in range(n - 1):u, v = map(int, input().split())g[u].append(v)g[v].append(u)res = 0def dfs(u, pre):global rest = [0, 0]if s[u - 1] == 'B':t[0] = 1else:t[1] = 1for v in g[u]:if v != pre:child = dfs(v, u)t[0] |= child[0]t[1] |= child[1]if t[0] and t[1]:res += 1return tdfs(1, 0)print(res)
  • Java
import java.util.*;public class Main {static List<List<Integer>> g;static String s;static int res = 0;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();s = sc.next();g = new ArrayList<>();for (int i = 0; i <= n; i++) {g.add(new ArrayList<>());}for (int i = 0; i < n - 1; i++) {int u = sc.nextInt();int v = sc.nextInt();g.get(u).add(v);g.get(v).add(u);}dfs(1, 0);System.out.println(res);}static int[] dfs(int u, int pre) {int[] t = new int[2];if (s.charAt(u - 1) == 'B')t[0] = 1;elset[1] = 1;for (int v : g.get(u)) {if (v != pre) {int[] child = dfs(v, u);t[0] |= child[0];t[1] |= child[1];}}if (t[0] == 1 && t[1] == 1)res++;return t;}
}

🧀 04.LYA的因子数量查询

问题描述

LYA有一个非常长的数组,数组中的元素都是正整数,且每个元素的取值范围为 1 1 1 10 10 10。为了方便描述,数组以连续段的形式给出,每个连续段用一个二元组 ( u i , v i ) (u_i, v_i) (ui,vi) 表示,其中 u i u_i ui 表示该段中的元素值, v i v_i vi 表示该段的长度。

现在,LYA需要进行 q q q 次查询,每次查询给定一个区间 [ l , r ] [l, r] [l,r],请你帮助她计算出该区间内所有元素的乘积的因子数量。由于答案可能很大,请对 1 0 9 + 7 10^9+7 109+7 取模后输出。

输入格式

第一行包含两个正整数 n n n m m m,分别表示数组的长度和连续段的数量。

接下来 m m m 行,每行包含两个正整数 u i u_i ui v i v_i vi,表示一个连续段。

m + 2 m+2 m+2 行包含一个正整数 q q q,表示查询的次数。

接下来 q q q 行,每行包含两个正整数 l l l r r r,表示一次查询的区间。

输出格式

输出共 q q q 行,每行输出一个整数,表示对应查询区间内所有元素的乘积的因子数量对 1 0 9 + 7 10^9+7 109+7 取模后的结果。

样例输入

6 3
1 2
2 1
3 3
2
1 3
2 6

样例输出

2
8

数据范围

1 ≤ n ≤ 1 0 14 1 \leq n \leq 10^{14} 1n1014
1 ≤ m , q ≤ 1 0 5 1 \leq m, q \leq 10^5 1m,q105
1 ≤ u i ≤ 10 1 \leq u_i \leq 10 1ui10
1 ≤ v i ≤ 1 0 9 1 \leq v_i \leq 10^9 1vi109
1 ≤ l ≤ r ≤ n 1 \leq l \leq r \leq n 1lrn
保证所有 v i v_i vi 之和等于 n n n

题解

本题可以使用线段树来解决。首先,我们可以预处理出每个数字 1 1 1 10 10 10 的质因子分解结果,存储在一个字典 factors_dict 中。然后,我们可以构建一棵线段树,树上的每个节点维护一个字典,表示该节点对应区间内每个质因子的次数。

对于每个连续段 ( u i , v i ) (u_i, v_i) (ui,vi),我们可以将其对应的质因子次数加到线段树的对应区间上。

对于每次查询 [ l , r ] [l, r] [l,r],我们可以通过线段树的区间查询,得到区间 [ l , r ] [l, r] [l,r] 内每个质因子的次数。然后,我们可以根据质因子次数计算出因子数量。设区间 [ l , r ] [l, r] [l,r] 内第 i i i 个质因子的次数为 c i c_i ci,则因子数量为 ∏ i ( c i + 1 ) \prod_{i} (c_i+1) i(ci+1)

最后,将因子数量对 1 0 9 + 7 10^9+7 109+7 取模后输出即可。

时间复杂度: O ( ( n + q ) log ⁡ n ) O((n+q) \log n) O((n+q)logn),其中 n n n 为数组长度, q q q 为查询次数。
空间复杂度: O ( n ) O(n) O(n)

参考代码

from collections import defaultdictMOD = 10 ** 9 + 7def prime_factors(n):factors = {}i = 2while i * i <= n:while n % i == 0:factors[i] = factors.get(i, 0) + 1n //= ii += 1if n > 1:factors[n] = 1return factorsfactors_dict = {i: prime_factors(i) for i in range(1, 11)}def build_tree(node, start, end):if start == end:tree[node] = defaultdict(int)returnmid = (start + end) // 2build_tree(node * 2, start, mid)build_tree(node * 2 + 1, mid + 1, end)tree[node] = defaultdict(int)def update_tree(node, start, end, l, r, val):if r < start or end < l:returnif l <= start and end <= r:for fc, pow in factors_dict[val].items():tree[node][fc] += pow * (end - start + 1)returnmid = (start + end) // 2update_tree(node * 2, start, mid, l, r, val)update_tree(node * 2 + 1, mid + 1, end, l, r, val)for fc in set(tree[node * 2]) | set(tree[node * 2 + 1]):tree[node][fc] = tree[node * 2][fc] + tree[node * 2 + 1][fc]def query_tree(node, start, end, l, r):if r < start or end < l:return defaultdict(int)if l <= start and end <= r:return tree[node]mid = (start + end) // 2left = query_tree(node * 2, start, mid, l, r)right = query_tree(node * 2 + 1, mid + 1, end, l, r)factors = defaultdict(int)for fc in set(left) | set(right):factors[fc] = left[fc] + right[fc]return factorsn, m = map(int, input().split())
tree = [None] * (4 * n)
build_tree(1, 1, n)index = 1
for _ in range(m):ui, vi = map(int, input().split())update_tree(1, 1, n, index, index + vi - 1, ui)index += viq = int(input())
for _ in range(q):l, r = map(int, input().split())factors = query_tree(1, 1, n, l, r)ans = 1for pow in factors.values():ans = ans * (pow + 1) % MODprint(ans)
  • Java
import java.io.*;
import java.util.*;public class Main {static final int MOD = (int) 1e9 + 7;static Map<Integer, Map<Integer, Integer>> factorsDict;static Map<Integer, Integer>[] tree;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] line = br.readLine().split(" ");int n = Integer.parseInt(line[0]);int m = Integer.parseInt(line[1]);factorsDict = new HashMap<>();for (int i = 1; i <= 10; i++) {factorsDict.put(i, primeFactors(i));}tree = new Map[4 * n];buildTree(1, 1, n);int index = 1;for (int i = 0; i < m; i++) {line = br.readLine().split(" ");int ui = Integer.parseInt(line[0]);int vi = Integer.parseInt(line[1]);updateTree(1, 1, n, index, index + vi - 1, ui);index += vi;}int q = Integer.parseInt(br.readLine());for (int i = 0; i < q; i++) {line = br.readLine().split(" ");int l = Integer.parseInt(line[0]);int r = Integer.parseInt(line[1]);Map<Integer, Integer> factors = queryTree(1, 1, n, l, r);long ans = 1;for (int pow : factors.values()) {ans = ans * (pow + 1) % MOD;}System.out.println(ans);}}static Map<Integer, Integer> primeFactors(int n) {Map<Integer, Integer> factors = new HashMap<>();int i = 2;while (i * i <= n) {while (n % i == 0) {factors.put(i, factors.getOrDefault(i, 0) + 1);n /= i;}i++;}if (n > 1) {factors.put(n, 1);}return factors;}static void buildTree(int node, int start, int end) {if (start == end) {tree[node] = new HashMap<>();return;}int mid = (start + end) / 2;buildTree(node * 2, start, mid);buildTree(node * 2 + 1, mid + 1, end);tree[node] = new HashMap<>();}static void updateTree(int node, int start, int end, int l, int r, int val) {if (r < start || end < l) {return;}if (l <= start && end <= r) {for (Map.Entry<Integer, Integer> entry : factorsDict.get(val).entrySet()) {int fc = entry.getKey();int pow = entry.getValue();tree[node].put(fc, tree[node].getOrDefault(fc, 0) + pow * (end - start + 1));}return;}int mid = (start + end) / 2;updateTree(node * 2, start, mid, l, r, val);updateTree(node * 2 + 1, mid + 1, end, l, r, val);for (int fc : new HashSet<>(tree[node * 2].keySet())) {tree[node].put(fc, tree[node * 2].getOrDefault(fc, 0) + tree[node * 2 + 1].getOrDefault(fc, 0));}for (int fc : new HashSet<>(tree[node * 2 + 1].keySet())) {tree[node].put(fc, tree[node * 2].getOrDefault(fc, 0) + tree[node * 2 + 1].getOrDefault(fc, 0));}}static Map<Integer, Integer> queryTree(int node, int start, int end, int l, int r) {if (r < start || end < l) {return new HashMap<>();}if (l <= start && end <= r) {return tree[node];}int mid = (start + end) / 2;Map<Integer, Integer> left = queryTree(node * 2, start, mid, l, r);Map<Integer, Integer> right = queryTree(node * 2 + 1, mid + 1, end, l, r);Map<Integer, Integer> factors = new HashMap<>();for (int fc : new HashSet<>(left.keySet())) {factors.put(fc, left.getOrDefault(fc, 0) + right.getOrDefault(fc, 0));}for (int fc : new HashSet<>(right.keySet())) {factors.put(fc, left.getOrDefault(fc, 0) + right.getOrDefault(fc, 0));}return factors;}
}
  • Cpp
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;const int MOD = 1e9 + 7;
unordered_map<int, unordered_map<int, int>> factorsDict;
vector<unordered_map<int, int>> tree;unordered_map<int, int> primeFactors(int n) {unordered_map<int, int> factors;int i = 2;while (i * i <= n) {while (n % i == 0) {factors[i]++;n /= i;}i++;}if (n > 1) {factors[n] = 1;}return factors;
}void buildTree(int node, int start, int end) {if (start == end) {tree[node].clear();return;}int mid = (start + end) / 2;buildTree(node * 2, start, mid);buildTree(node * 2 + 1, mid + 1, end);tree[node].clear();
}void updateTree(int node, int start, int end, int l, int r, int val) {if (r < start || end < l) {return;}if (l <= start && end <= r) {for (auto entry : factorsDict[val]) {int fc = entry.first;int pow = entry.second;tree[node][fc] += pow * (end - start + 1);}return;}int mid = (start + end) / 2;updateTree(node * 2, start, mid, l, r, val);updateTree(node * 2 + 1, mid + 1, end, l, r, val);for (auto entry : tree[node * 2]) {int fc = entry.first;tree[node][fc] += entry.second;}for (auto entry : tree[node * 2 + 1]) {int fc = entry.first;tree[node][fc] += entry.second;}
}unordered_map<int, int> queryTree(int node, int start, int end, int l, int r) {if (r < start || end < l) {return {};}if (l <= start && end <= r) {return tree[node];}int mid = (start + end) / 2;auto left = queryTree(node * 2, start, mid, l, r);auto right = queryTree(node * 2 + 1, mid + 1, end, l, r);unordered_map<int, int> factors;for (auto entry : left) {int fc = entry.first;factors[fc] += entry.second;}for (auto entry : right) {int fc = entry.first;factors[fc] += entry.second;}return factors;
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);for (int i = 1; i <= 10; i++) {factorsDict[i] = primeFactors(i);}int n, m;cin >> n >> m;tree.resize(4 * n);buildTree(1, 1, n);int index = 1;for (int i = 0; i < m; i++) {int ui, vi;cin >> ui >> vi;updateTree(1, 1, n, index, index + vi - 1, ui);index += vi;}int q;cin >> q;while (q--) {int l, r;cin >> l >> r;auto factors = queryTree(1, 1, n, l, r);long long ans = 1;for (auto entry : factors) {int pow = entry.second;ans = ans * (pow + 1) % MOD;}cout << ans << '\n';}return 0;
}

🍅 05.LYA的字符串子序列集合

问题描述

LYA有一个由数字组成的字符串 s s s。她从 s s s 中选出了所有的非空子序列,并将其中满足相邻字符不相同的子序列都加入到了集合 S S S 中。现在她想知道,集合 S S S 中有多少个不同的子序列。注意,允许子序列以 0 0 0 开头,并且以 0 0 0 开头的子序列和不以 0 0 0 开头的子序列是不同的。

输入格式

输入包含一行,为一个由数字组成的字符串 s s s,表示LYA的字符串。字符串 s s s 的长度不超过 1 0 6 10^6 106,可能包含前导 0 0 0

输出格式

输出包含一行,为一个整数,表示集合 S S S 中不同子序列的数量。答案可能很大,请对 1 0 9 + 7 10^9+7 109+7 取模后输出。

样例输入

12121

样例输出

9

数据范围

0 ≤ s ≤ 1 0 1000000 0 \leq s \leq 10^{1000000} 0s101000000

题解

这道题可以使用动态规划来解决。设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示考虑前 i i i 个字符,最后一个字符为 j j j 的满足条件的子序列的数量。初始化 d p [ i n t ( x ) ] = 1 dp[int(x)] = 1 dp[int(x)]=1,表示只考虑第一个字符时,以该字符结尾的子序列数量为 1 1 1。对于第 i i i 个字符 c c c,需要更新 d p [ i ] [ j ] dp[i][j] dp[i][j]:

  • 如果 j ≠ c j \neq c j=c,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j],因为以 j j j 结尾的子序列数量不变。
  • 如果 j = c j = c j=c,则 d p [ i ] [ c ] = ∑ k = 0 9 d p [ i − 1 ] [ k ] − d p [ i − 1 ] [ c ] + 1 dp[i][c] = \sum_{k=0}^9 dp[i-1][k] - dp[i-1][c] + 1 dp[i][c]=k=09dp[i1][k]dp[i1][c]+1,因为以 c c c 结尾的子序列数量等于前 i − 1 i-1 i1 个字符的所有子序列数量,再减去前 i − 1 i-1 i1 个字符中以 c c c 结尾的子序列数量,最后加上空序列。

最终答案为 ∑ j = 0 9 d p [ n ] [ j ] \sum_{j=0}^9 dp[n][j] j=09dp[n][j],即考虑所有字符后,以任意字符结尾的满足条件的子序列数量之和。时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)

参考代码

  • Python
#include <iostream>
using namespace std;const int MOD = 1e9 + 7;int main() {string s;cin >> s;int n = s.length();long long dp[n + 1][10];for (int i = 0; i <= n; i++) {for (int j = 0; j < 10; j++) {dp[i][j] = 0;}}dp[1][s[0] - '0'] = 1;for (int i = 2; i <= n; i++) {for (int j = 0; j < 10; j++) {if (j != s[i - 1] - '0') {dp[i][j] = dp[i - 1][j];}}long long sum = 0;for (int j = 0; j < 10; j++) {sum = (sum + dp[i - 1][j]) % MOD;}dp[i][s[i - 1] - '0'] = (sum - dp[i - 1][s[i - 1] - '0'] + 1 + MOD) % MOD;}long long ans = 0;for (int j = 0; j < 10; j++) {ans = (ans + dp[n][j]) % MOD;}cout << ans << endl;return 0;
}
  • Java
import java.util.Scanner;public class Main {static final int MOD = (int) 1e9 + 7;public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s = sc.next();int n = s.length();long[][] dp = new long[n + 1][10];dp[1][s.charAt(0) - '0'] = 1;for (int i = 2; i <= n; i++) {for (int j = 0; j < 10; j++) {if (j != s.charAt(i - 1) - '0') {dp[i][j] = dp[i - 1][j];}}long sum = 0;for (int j = 0; j < 10; j++) {sum = (sum + dp[i - 1][j]) % MOD;}dp[i][s.charAt(i - 1) - '0'] = (sum - dp[i - 1][s.charAt(i - 1) - '0'] + 1 + MOD) % MOD;}long ans = 0;for (int j = 0; j < 10; j++) {ans = (ans + dp[n][j]) % MOD;}System.out.println(ans);}
}
  • Cpp
#include <iostream>
using namespace std;const int MOD = 1e9 + 7;int main() {string s;cin >> s;int n = s.length();long long dp[n + 1];dp[0] = 1;int last[10];for (int i = 0; i < 10; i++) {last[i] = -1;}for (int i = 1; i <= n; i++) {int digit = s[i - 1] - '0';if (i == 1 || s[i - 1] != s[i - 2]) {dp[i] = dp[i - 1] * 2 % MOD;} else {dp[i] = dp[last[digit] + 1] * 2 % MOD;}if (last[digit] != -1) {dp[i] -= dp[last[digit]];}dp[i] = (dp[i] + MOD) % MOD;last[digit] = i;}cout << (dp[n] - 1 + MOD) % MOD << endl;return 0;
}

写在最后

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新。

在这里插入图片描述

这篇关于【美团笔试题汇总】2024-04-13-美团春秋招笔试题-三语言题解(CPP/Python/Java)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/901914

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一