【算法题笔记】美团2024年春招第一场笔试【技术】

A. 小美的平衡矩阵

1. 题目

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

2. 输入描述

第一行输入一个正整数 n ,代表矩阵大小。
接下来的 n 行,每行输入一个长度为 n 的 01 串,用来表示矩阵。(1≤n≤200)

3. 输出描述

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

4. 示例

输入

4
1010
0101
1100
0011

输出

0
7
0
1

5. 题解(C)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int n;
    scanf("%d", &n);
    int matrix[200][200];
    int dp[200][200];
    for (int i = 1; i <= n; i++) {
        char* t = (char*)malloc(200 * sizeof(char));
        scanf("%s", t);
        for (int j = 1; j <= n; j++) {
            matrix[i][j] = t[j - 1] - '0';
        }
        free(t);
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + matrix[i][j];
        }
    }
    // for (int i = 0; i <= n; i++) {
    //     for (int j = 0; j <= n; j ++) {
    //         printf("%d ", matrix[i][j]);
    //     }
    //     printf("\n");
    // }
    // for (int i = 0; i <= n; i++) {
    //     for (int j = 0; j <= n; j ++) {
    //         printf("%d ", dp[i][j]);
    //     }
    //     printf("\n");
    // }
    for (int i = 1; i <= n; i++) {
        if (i % 2 != 0) {
            printf("0\n");
            continue;
        }
        int ans = 0, sum;
        for (int j = 1; j <= n; j++) {
            for (int k = 1; k <= n; k++) {
                if (j >= i && k >= i){
                    sum = dp[j][k] - dp[j - i][k] - dp[j][k - i] + dp[j - i][k - i];
                    if (sum == i * i / 2) ans++;
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

B. 小美的数组询问

1. 题目

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

2. 输入描述

第一行输入两个正整数 n,q,代表数组大小和询问次数。
第二行输入n个整数 ai,其中如果输入的 ai 为 0,那么说明 ai 是未知的。
接下来的 q 行,每行输入两个正整数 l,r,代表一次询问。
1 ≤ n,q ≤ 105
0 ≤ ai ≤ 109
1 ≤ l ≤ r ≤ 109

3. 输出描述

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

4. 示例

输入

3 2
1 0 3
1 2
4 4

输出

5 6
8 8

5. 题解(C)

#include <stdio.h>

int main() {
    int n, q;
    scanf("%d %d", &n, &q);
    long long sum = 0;
    int zeros = 0;
    for (int i = 0; i < n; i++) {
        int a;
        scanf("%d", &a);
        if (a == 0) zeros++;
        else sum += a;
    }
    while (q--) {
        int l, r;
        scanf("%d %d", &l, &r);
        long long maximum = sum + zeros * r;
        long long minimum = sum + zeros * l;
        printf("%lld %lld\n", minimum, maximum);
    }
    return 0;
}

C. 小美的MT

1. 题目

MT 是美团的缩写,因此小美很喜欢这两个字母。
现在小美拿到了一个仅由大写字母组成字符串,她可以最多操作 k 次,每次可以修改任意一个字符。小美想知道,操作结束后最多共有多少个 ‘M’ 和 ‘T’ 字符?

2. 输入描述

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

3. 输出描述

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

4. 示例

输入

5 2
MTUAN

输出

4

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

5. 题解(C)

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n, k;
    scanf("%d %d", &n, &k);
    char* s = (char*)malloc(n * sizeof(char));
    scanf("%s", s);
    int cnt = 0;
    for(int i = 0; i < n; i++){
        if(s[i] == 'M' || s[i] == 'T') cnt++;
    }
    int ans = (cnt + k < n) ? cnt + k : n;
    printf("%d", ans);
    return 0;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值