【备战春招必看】美团2025届春招第1套笔试解析 | 大厂真题通关指南

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺
  • 配套练习题库

互联网必备刷题宝典🔗

📢 美团技术岗笔试重要信息速览

⏰ 笔试时间安排

  • 常规场次:每周六交替进行
    • 上午场 10:00~11:30
    • 晚间场 19:00~20:30
  • 通知时间:每周四/五通过邮箱发送考试链接

🧩 笔试题型分布

岗位类型 题目构成
算法岗 选择题 + 5道编程
后端开发岗 选择题 + 3道编程
前端/测试岗 选择题 + 2道编程

⚙️ 考试设置要点

  • 考试平台:牛客网(ACM模式)
  • 监考要求
    • 必须开启笔记本前置摄像头
    • 禁止使用手机(需小程序锁定)
    • 允许使用本地IDE
  • 编程规范
    • 严格遵循输入输出格式
    • 注意时间复杂度控制(通常1s对应1e8次运算)

📚 笔试经验贴

(所有展示题面均已进行改编处理,保留核心考点)

本题库收录整理自:

  1. 互联网公开的笔试真题回忆版(经网友投稿)
  2. 各大技术社区公开讨论的经典题型
  3. 历年校招考生提供的解题思路

🔍 题库特点:

  • 100%真实笔试场景还原
  • 包含高频考点题型
  • 提供多语言实现参考
  • 持续更新2024届最新真题

⚠️ 注意事项:

  1. 所有题目均来自公开渠道,已进行改编脱敏处理
  2. 实际笔试可能出现题型变化,请以官方通知为准

🚀 春招备战指南

金三银四求职季即将到来!这里整理了最新美团真题及解析,助你快速掌握笔试套路。建议重点突破以下题型:

  1. 数组/字符串操作
  2. 树形结构应用
  3. 贪心/动态规划
  4. 区间合并问题

(👇 下附最新笔试真题及详细解析 👇)

真题详解(改编版)

T1

题目内容

小基很喜欢 M 和 T 这两个字母。现在小基拿到了一个仅由大写字母组成的字符串,他可以最多操作 次,每次可以修改任意一个字符。小基想知道,操作结束后最多共有多少个 M 和 T 字符?

输入描述

第一行输入两个正整数 ,代表字符串长度和操作次数。 第二行输入一个长度为 的、仅由大写字母组成的字符串。 其中,

输出描述

输出操作结束后最多共有多少个 M 和 T 字符。

样例1

输入:

5 2
MTUAN

输出:

4

说明:修改第三个和第五个字符,形成的为 MTTAM,这样共有 4 个 M 和 T。

题解

这是一道贪心思维题,解题的关键在于理解如何最大化 M 和 T 的数量。

首先统计字符串中非 M 和 T 的字符数量,记为 。这些字符都是可以被修改的候选。

有了操作次数 的限制,实际可修改的字符数量就是 。为什么取最小值?因为即使操作次数很多,能修改的字符数量也不能超过现有的非 M 和 T 字符的数量。

最终答案就是:原有的 M 和 T 的数量加上新增的 M 和 T 的数量,即

以样例为例:字符串"MTUAN"中有 3 个非 M 和 T 的字符(U、A、N),操作次数 ,所以最多可以将其中 2 个字符改为 M 或 T,最终得到 4 个 M 和 T。

时间复杂度为 ,只需要遍历一次字符串统计字符数量即可。对于给定的数据范围()来说完全足够。

参考代码

C++:

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    
    int cnt = 0;
    for(char c : s) {
        if(c != 'M' && c != 'T') cnt++;
    }
    
    cout << n - cnt + min(k, cnt) << endl;
    return 0;
}

Python:

n, k = map(int, input().split())
s = input()

cnt = sum(1 for c in s if c not in 'MT')
print(n - cnt + min(k, cnt))

Java:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        String s = sc.next();
        
        int cnt = 0;
        for(char c : s.toCharArray()) {
            if(c != 'M' && c != 'T') cnt++;
        }
        
        System.out.println(n - cnt + Math.min(k, cnt));
    }
}

T2

题目内容

小基拿到了一个由正整数组成的数组,但其中有一些元素是未知的(用 0 来表示)。现在小基想知道,如果那些未知的元素在区间 范围内随机取值的话,数组所有元素之和的最小值和最大值分别是多少?共有 次询问。

输入描述

第一行整数 ,表示数组的长度和询问的次数。 第二行输入 个整数 ,其中如果输入的 为 0,那么说明 是未知的。 接下来的 行,每行输入两个正整数 ,代表一次询问。

数据范围:

输出描述

输出 行,每行输出两个正整数,代表所有元素之和的最小值和最大值。

样例1

输入:

3 2
3 0 2
1 1
1 2

输出:

6 6
6 7

说明:第二次询问中,最小为 ,最大为

题解

这是一道思维题,关键在于理解如何获取最大值和最小值。

对于每个未知数(值为 0 的位置),要使总和最小,显然应该取可选范围的最小值 ;要使总和最大,则应该取可选范围的最大值

解题步骤如下:

  1. 统计数组中值为 0 的元素个数,记为
  2. 统计数组中所有非 0 元素的和,记为
  3. 对于每次询问:
    • 最小值 =
    • 最大值 =

注意:由于数据范围较大(),计算时需要使用 long long 类型避免溢出。

时间复杂度分析:

  • 预处理数组需要
  • 每次询问只需 的计算
  • 总时间复杂度为 对于给定的数据范围()完全可以接受。

参考代码

C++:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main() {
    int n, q;
    cin >> n >> q;
    
    ll sum = 0;
    int zero_cnt = 0;
    for(int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if(x == 0) zero_cnt++;
        else sum += x;
    }
    
    while(q--) {
        ll l, r;
        cin >> l >> r;
        cout << sum + zero_cnt * l << " " << sum + zero_cnt * r << endl;
    }
    return 0;
}

Python:

n, q = map(int, input().split())
a = list(map(int, input().split()))

sum_val = sum(x for x in a if x != 0)
zero_cnt = a.count(0)

for _ in range(q):
    l, r = map(int, input().split())
    print(sum_val + zero_cnt * l, sum_val + zero_cnt * r)

Java:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int q = sc.nextInt();
        
        long sum = 0;
        int zeroCnt = 0;
        for(int i = 0; i < n; i++) {
            int x = sc.nextInt();
            if(x == 0) zeroCnt++;
            else sum += x;
        }
        
        while(q-- > 0) {
            long l = sc.nextLong();
            long r = sc.nextLong();
            System.out.println((sum + zeroCnt * l) + " " + (sum + zeroCnt * r));
        }
    }
}

T3

题目内容

小基拿到了一个 的矩阵,其中每个元素是 0 或者 1。小基认为一个矩形区域是完美的,当且仅当该区域内 0 的数量等于 1 的数量。现在,小基希望知道有多少个 的完美矩形区域。需要回答 的所有答案。

输入描述

第一行输入一个正整数 ,代表矩阵大小。 接下来的 行,每行输入一个长度为 的 01 串,用来表示矩阵。 其中,

输出描述

输出 行,第 行输出 的完美矩形区域的数量。

样例1

输入:

4
1010
0101
1100
0011

输出:

0
7
0
1

题解

这道题目可以使用二维前缀和来解决。

核心思路:

  1. 先预处理出二维前缀和数组,用于快速计算任意矩形区域内 1 的个数。
  2. 枚举所有可能的正方形区域,检查是否完美。
  3. 一个区域要完美,需要区域内 0 和 1 的数量相等,即 1 的数量应该是区域大小的一半。

具体实现步骤:

  1. 构建前缀和数组 ,表示从 的矩形区域内 1 的个数。
  2. 对于每个边长 ,枚举左上角坐标
  3. 计算对应的右下角坐标
  4. 使用前缀和计算该区域内 1 的个数,判断是否等于区域大小的一半。

时间复杂度分析:

  • 预处理前缀和需要
  • 枚举所有可能的正方形需要
  • 总时间复杂度为 的数据范围内可以通过。

参考代码

C++:

#include <bits/stdc++.h>
using namespace std;

const int N = 205;
int sum[N][N], n;
char g[N][N];

int get_sum(int x1, int y1, int x2, int y2) {
    return sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1];
}

int main() {
    cin >> n;
    // 读入矩阵并构建前缀和数组
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cin >> g[i][j];
            sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + (g[i][j] == '1');
        }
    }
    
    // 枚举所有可能的正方形大小
    for(int len = 1; len <= n; len++) {
        int ans = 0;
        // 枚举左上角坐标
        for(int i = 1; i + len - 1 <= n; i++) {
            for(int j = 1; j + len - 1 <= n; j++) {
                int ones = get_sum(i, j, i + len - 1, j + len - 1);
                if(ones * 2 == len * len) ans++;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

Python:

n = int(input())
grid = ['0' * (n+1)] + ['0' + input() for _ in range(n)]

# 构建前缀和数组
sum_matrix = [[0] * (n+1) for _ in range(n+1)]
for i in range(1, n+1):
    for j in range(1, n+1):
        sum_matrix[i][j] = (sum_matrix[i-1][j] + 
                           sum_matrix[i][j-1] - 
                           sum_matrix[i-1][j-1] + 
                           int(grid[i][j] == '1'))

def get_sum(x1, y1, x2, y2):
    return (sum_matrix[x2][y2] - 
            sum_matrix[x1-1][y2] - 
            sum_matrix[x2][y1-1] + 
            sum_matrix[x1-1][y1-1])

# 枚举所有可能的正方形大小
for length in range(1, n+1):
    ans = 0
    # 枚举左上角坐标
    for i in range(1, n-length+2):
        for j in range(1, n-length+2):
            ones = get_sum(i, j, i+length-1, j+length-1)
            if ones * 2 == length * length:
                ans += 1
    print(ans)

Java:

import java.util.*;

public class Main {
    static int N = 205;
    static int[][] sum = new int[N][N];
    static char[][] g = new char[N][N];
    static int n;
    
    static int getSum(int x1, int y1, int x2, int y2) {
        return sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1];
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        sc.nextLine(); // 消耗换行符
        
        // 读入矩阵并构建前缀和数组
        for(int i = 1; i <= n; i++) {
            String line = sc.nextLine();
            for(int j = 1; j <= n; j++) {
                g[i][j] = line.charAt(j-1);
                sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + 
                           (g[i][j] == '1' ? 1 : 0);
            }
        }
        
        // 枚举所有可能的正方形大小
        for(int len = 1; len <= n; len++) {
            int ans = 0;
            // 枚举左上角坐标
            for(int i = 1; i + len - 1 <= n; i++) {
                for(int j = 1; j + len - 1 <= n; j++) {
                    int ones = getSum(i, j, i + len - 1, j + len - 1);
                    if(ones * 2 == len * len) ans++;
                }
            }
            System.out.println(ans);
        }
    }
}

T4

题目内容

小基拿到了一个大小为 的数组,他希望删除一个区间后,使得剩余所有元素的乘积末尾至少有 个 0。小基想知道,一共有多少种不同的删除方案?

输入描述

第一行输入两个正整数 。 第二行输入 个正整数 ,代表小基拿到的数组。 其中,

输出描述

输出一个整数,代表删除的方案数。

样例1

输入:

5 2
2 5 3 4 20

输出:

4

题解

这道题目使用双指针算法求解,关键思路如下:

  1. 统计整个数组中每个数的因子 2 和因子 5 的个数。
  2. 使用双指针维护删除区间,计算剩余数字中因子的总数。
  3. 当某个区间删除后不满足条件时,需要缩小删除区间。
  4. 当某个区间满足条件时,可以计算以当前右端点结尾的所有合法方案。

时间复杂度分析:

  • 预处理因子个数:
  • 双指针遍历: 总体复杂度:

参考代码

C++:

#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int l = 0, r = 0;
    int n, k;
    cin >> n >> k;
    
    vector<int> a(n);
    vector<array<int, 2>> cnt(n);
    
    // 统计每个数的因子2和5的个数
    for(int i = 0; i < n; i++) {
        cin >> a[i];
        int x = a[i];
        while(x % 2 == 0) x >>= 1, l++, cnt[i][0]++;
        while(x % 5 == 0) x /= 5, r++, cnt[i][1]++;
    }
    
    int res = 0;
    array<int, 2> c{l, r};  // 记录当前未被删除的数中因子2和5的总数
    int j = 0;  // 左指针
    
    // 枚举右指针
    for(int i = 0; i < n; i++) {
        // 删除当前位置的数
        for(int p = 0; p < 2; p++)
            c[p] -= cnt[i][p];
            
        // 当不满足条件时,缩小删除区间
        while(j <= i && *min_element(c.begin(), c.end()) < k) {
            for(int p = 0; p < 2; p++)
                c[p] += cnt[j][p];
            j++;
        }
        
  

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

后来123321:别着急,我学院本大二,投了1100份,两个面试,其中一个还是我去线下招聘会投的简历,有时候这东西也得看运气
点赞 评论 收藏
分享
牛客383479252号:9,2学生暑期实习失利开始投小厂,给这群人整自信了
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务