美团笔试 美团实习 0415

笔试时间:2023年04月15日

第一题

题目:字符串的前缀

现在有两个字符串S和T,你需要对S进行若干次操作,使得S是T的一个前缀(空串也是一个前缀)。每次操作可以修改S的一个字符,或者删除一个S末尾的字符。小团需要写一段程序,输出最少需要操作的次数。

输入描述

第一行一个正整数C,表示数据组数;

对于每一组数据输入两行仅包含小写字母的字符串S和T。

输出描述

对于每一组数据,输出一个整数,表示最少需要操作的次数。

样例输入

2

aba

abb

abcd

efg

样例输出

1

4

提示:

第一组数据,可以修改最后一个字母,使得S=abb,是T的一个前缀;第二组数据,需要将S整个串删除,操作次数为4。

参考题解

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <string>
using namespace std;

int main() {
    int C;
    cin >> C;
    cin.ignore(); // Ignore the newline after reading C

    for (int i = 0; i < C; ++i) {
        string S, T;
        getline(cin, S);
        getline(cin, T);

        int res = 0;
        int pos = 0;

        if (S.length() > T.length()) {
            res = S.length() - T.length();
            pos = T.length() - 1;
        } else {
            pos = S.length() - 1;
        }

        bool flag = false;

        while (pos >= 0) {
            if (!flag) {
                if (S[pos] == T[pos]) {
                    flag = true;
                } else {
                    res++;
                }
            } else {
                if (S[pos] != T[pos]) {
                    res++;
                }
            }

            pos--;
        }

        cout << res << endl;
    }

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int C = scanner.nextInt();
        scanner.nextLine(); // Consume newline

        for (int i = 0; i < C; ++i) {
            String S = scanner.nextLine();
            String T = scanner.nextLine();

            int res = 0;
            int pos = 0;

            if (S.length() > T.length()) {
                res = S.length() - T.length();
                pos = T.length() - 1;
            } else {
                pos = S.length() - 1;
            }

            boolean flag = false;

            while (pos >= 0) {
                if (!flag) {
                    if (S.charAt(pos) == T.charAt(pos)) {
                        flag = true;
                    } else {
                        res++;
                    }
                } else {
                    if (S.charAt(pos) != T.charAt(pos)) {
                        res++;
                    }
                }

                pos--;
            }

            System.out.println(res);
        }
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

C = int(input())
for _ in range(C):
    S = input()
    T = input()
    res, pos = 0, 0
    if len(S) > len(T):
        res = len(S) - len(T)
        pos = len(T) - 1
    else:
        pos = len(S) - 1 
    flag = False
    while pos >= 0:
        if not flag:
            if S[pos] == T[pos]:
                flag = True
            else:
                res += 1
        else:
            if S[pos] != T[pos]: res += 1
        pos -= 1
    print(res)

第二题

题目:小美分糖

某一天,小美从商店买了两种糖果,分别买了a个和b个,要分给班上n个小朋友。为了不浪费,每块糖果都得恰好分到一个小朋友。另外,两种糖果一起吃的话味道其实并不好,所以每一个小朋友都只能得到其中一种糖果。小美希望分得最少糖果的那个小朋友能得到尽量多的糖果。小美的任务是求得这个数量是多少。

输入描述

第一行一个正整数T,表示有T组数据。

对于每一组数据,输入一行n,a,b,中间用空格隔开。

1≤a,b≤10000,  2≤n≤a+b, 1≤T≤100

输出描述

对于每一组数据,输出仅一行一个整数,表示答案。

样例输入

2

5 2 3

4 7 10

样例输出

1

3

提示:

第一组数据,每个小朋友都恰好分得一个糖果;第二组数据,可以分成:(3个第一种,4个第一种,5个第二种,5个第二种),这样第一个小朋友分得最少,没有其他方案使得分得最少的那个小朋友的糖果数量更大。

参考题解

二分答案。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
using namespace std;

bool check(long long x, long long n, long long a, long long b) {
    long long r1 = min(a, b);
    long long r2 = max(a, b);
    long long cnt = 1;
    r2 -= x;
    cnt += (r2 / x) + (r1 / x);
    return cnt >= n;
}

int main() {
    int T;
    cin >> T;

    for (int t = 0; t < T; ++t) {
        long long n, a, b;
        cin >> n >> a >> b;

        long long l = 0;
        long long r = max(a, b);

        while (l < r) {
            long long mid = (l + r + 1) >> 1;
            if (check(mid, n, a, b)) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }

        cout << r << endl;
    }

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    public static boolean check(long x, long n, long a, long b) {
        long r1 = Math.min(a, b);
        long r2 = Math.max(a, b);
        long cnt = 1;
        r2 -= x;
        cnt += (r2 / x) + (r1 / x);
        return cnt >= n;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();

        for (int t = 0; t < T; ++t) {
            long n = scanner.nextLong();
            long a = scanner.nextLong();
            long b = scanner.nextLong();

            long l = 0;
            long r = Math.max(a, b);

            while (l < r) {
                long mid = (l + r + 1) >> 1;
                if (check(mid, n, a, b)) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }

            System.out.println(r);
        }
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

T = int(input())

for _ in range(T):
    n, a, b = map(int, input().strip().split(" "))
    def check(x):
        r1, r2 = min(a,b), max(a,b)
        cnt = 1
        r2 -= x
        cnt += (r2 //x) + (r1 //x) 
        '''一个人分x  其他人x+1, 如果可以就ok'''
        return cnt >= n
        
            
    l, r = 0, max(a,b)
    while l < r:
        mid = (l + r + 1) >> 1
        if check(mid):l = mid
        else:  r = mid - 1
    print(r)

第三题

题目:交通规则

A国有n个城市,这n个城市排成一列,依次编号为1,2,3,...,n。一开始,这n座城市之间都没有任何交通路线,于是政府打算修建一些铁路来进行交通规划。接下来T天,每一天会进行如下操作的其中一种:- “L x”:表示编号为 x 的城市与其左边的城市之间修建一条铁路。如果 x 左边没有城市或者已经修建了铁路,则无视该操作;- “R x”:表示编号为 x 的城市与其右边的城市之间修建一条铁路。如果 x 右边没有城市或者已经修建了铁路,则无视该操作;- “Q x”:表示查询 x 往左边和往右边最远能到达的城市编号。你的任务是模拟以上操作,并对于每一条“Q x”操作,输出对应的答案。

输入描述

第一行输入两个正整数 n , T ;

接下来T行,每行输入形如题面中的其中一种。

1≤n≤10000, 1≤T≤200, 1≤x≤n

输出描述

对于每一个"Q x”操作,输出一行两个正整数,分别表示 x 往左边和往右边最远能到达的城市编号,中间用空格隔开。

样例输入

3 5

Q 2

L 2

Q 2

R 2

Q 2

样例输出

2 2

1 2

1 3

提示:

“Q 2”:一开始城市2没有与左边和右边联通,故最左和最右都是城市2;“L 2”:城市2与城市1联通;“Q 2”:此时最左能够到达城市1,最右能到达城市2;“R 2”:城市2与城市3联通:“Q 2”:此时最左能够到达城市1,最右能到达城市3;

参考题解

结合并查集+二分查找做法。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector<int> fa;

int find(int x) {
    if (x == fa[x]) return x;
    fa[x] = find(fa[x]);
    return fa[x];
}

void unite(int x, int y) {
    fa[find(x)] = find(y);
}

int main() {
    int n, T;
    cin >> n >> T;
    fa.resize(n + 2);

    for (int i = 1; i <= n; i++) {
        fa[i] = i;
    }

    for (int i = 0; i < T; i++) {
        string op;
        int pos;
        cin >> op >> pos;

        if (op == "L") {
            unite(pos, pos - 1);
        } else if (op == "R") {
            unite(pos, pos + 1);
        } else {
            int l = 1, r = pos;

            while (l < r) {
                int mid = (l + r) >> 1;
                if (find(pos) == find(mid)) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }

            int res1 = r;
            l = pos, r = n;

            while (l < r) {
                int mid = (l + r + 1) >> 1;
                if (find(pos) == find(mid)) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }

            cout << res1 << " " << r << endl;
        }
    }

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    static int[] fa;

    public static int find(int x) {
        if (x == fa[x]) return x;
        fa[x] = find(fa[x]);
        return fa[x];
    }

    public static void unite(int x, int y) {
        fa[find(x)] = find(y);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int T = scanner.nextInt();
        fa = new int[n + 2];

        for (int i = 1; i <= n; i++) {
            fa[i] = i;
        }

        for (int i = 0; i < T; i++) {
            String op = scanner.next();
            int pos = scanner.nextInt();

            if (op.equals("L")) {
                unite(pos, pos - 1);
            } else if (op.equals("R")) {
                unite(pos, pos + 1);
            } else {
                int l = 1, r = pos;

                while (l < r) {
                    int mid = (l + r) >> 1;
                    if (find(pos) == find(mid)) {
                        r = mid;
                    } else {
                        l = mid + 1;
                    }
                }

                int res1 = r;
                l = pos;
                r = n;

                while (l < r) {
                    int mid = (l + r + 1) >> 1;
                    if (find(pos) == find(mid)) {
                        l = mid;
                    } else {
                        r = mid - 1;
                    }
                }

                System.out.println(res1 + " " + r);
            }
        }
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

n, T = map(int, input().split(" "))

fa = [i for i in range(n+2)]

def find(x):
    if x == fa[x]: return x
    fa[x] = find(fa[x])
    return fa[x]

def union(x, y):
    fa[find(x)] = find(y)

for _ in range(T):
    line = input().strip().split(" ")
    op, pos = line[0], int(line[1])
    if op == 'L':
        union(pos, pos - 1)
    elif op == 'R':
        union(pos, pos + 1)
    else:
        '''左边二分找到连通的最小值'''
        l, r = 1,pos
        while l < r:
            mid = (l + r) >> 1
            if find(pos) == find(mid): r = mid
            else: l = mid + 1
        res1 = r
        l, r = pos, n
        while l < r:
            mid = (l + r + 1) >> 1
            if find(pos) == find(mid): l = mid
            else: r = mid - 1
        print(str(res1) + " " + str(r))

第四题

题目:小美玩套娃

小美最近喜欢上了玩套娃。具体的,小美有 n 个套娃,第 i 个套娃的大小为 ai,内部空间为 bi(bi≤ai)。对于两个套娃x,y, x能放入y中当且仅当ax≤by ,且放入后会占据 y 大小为 ax 的内部空间,即 y 的内部空间剩下 by-ax,每个套娃只能放在另外的一个套娃内,每个套娃内部也只能放一个套娃(当然内部放的这个套娃可以内部还有套娃)。显然套娃是套的越多越好,于是小美给每个套娃定义了一个价值 ci,如果套完之后套娃 i 还剩 k 的内部空间,小美需要付出ci*k 的花费,总花费为所有套娃的花费之和,现在小美想知道最小的花费为多少。

输入描述

第一行一个正整数 n ,表示套娃的个数

接下来三行每行 n 个整数,分别为

a1,a2,...an

b1,b2,...bn

c1,c2,...,cn

1≤n,ai,bi,ci,≤100000,bi≤ai

输出描述

输出一个整数表示最小的花费

样例输入

3

5 4 3

4 2 2

3 2 1

样例输出

6

提示:

将第二个套娃放在第一个里面,第三个不动,这样第一个套娃剩 0 的空间,第二个剩 2,第三个剩 2。总花费为0*3+2*2+2*1=6 。可以证明这是花费最小的方案。

参考题解

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    vector<int> b(n);
    vector<int> c(n);

    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    for (int i = 0; i < n; i++) {
        cin >> b[i];
    }

    for (int i = 0; i < n; i++) {
        cin >> c[i];
    }

    vector<vector<int>> taos1(n, vector<int>(4, 0));
    vector<vector<int>> taos2(n, vector<int>(4, 0));

    for (int i = 0; i < n; i++) {
        taos1[i][0] = a[i];
        taos1[i][1] = b[i];
        taos1[i][2] = c[i];
        taos1[i][3] = i;
        taos2[i][0] = a[i];
        taos2[i][1] = b[i];
        taos2[i][2] = c[i];
        taos2[i][3] = i;
    }

    sort(taos1.begin(), taos1.end(), [](vector<int>& x, vector<int>& y) {
        return x[0] < y[0];
    });

    sort(taos2.begin(), taos2.end(), [](vector<int>& x, vector<int>& y) {
        return x[2] < y[2];
    });

    long long res = 0;
    int rborder = n - 1;

    for (int i = n - 1; i >= 0; i--) {
        int l = 0, r = rborder;

        while (l < r) {
            int mid = (l + r + 1) >> 1;

            if (taos2[i][1] >= taos1[mid][0]) {
                l = mid;
            } else {
                l = mid + 1;
            }
        }

        if (taos1[r][3] == taos2[i][3]) {
            r--;
        }

        if (taos2[i][1] < taos1[r][0]) {
            break;
        }

        taos2[i][1] -= taos1[r][0];
        rborder = r - 1;
    }

    for (int i = 0; i < n; i++) {
        res += static_cast<long long>(taos2[i][1]) * taos2[i][2];
    }

    cout << res << endl;

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        int[] c = new int[n];

        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }

        for (int i = 0; i < n; i++) {
            b[i] = scanner.nextInt();
        }

        for (int i = 0; i < n; i++) {
            c[i] = scanner.nextInt();
        }

        int[][] taos1 = new int[n][4];
        int[][] taos2 = new int[n][4];

        for (int i = 0; i < n; i++) {
            taos1[i][0] = a[i];
            taos1[i][1] = b[i];
            taos1[i][2] = c[i];
            taos1[i][3] = i;
            taos2[i][0] = a[i];
            taos2[i][1] = b[i];
            taos2[i][2] = c[i];
            taos2[i][3] = i;
        }

        Arrays.sort(taos1, Comparator.comparingInt(x -> x[0]));
        Arrays.sort(taos2, Comparator.comparingInt(x -> x[2]));

        long res = 0;
        int rborder = n - 1;

        for (int i = n - 1; i >= 0; i--) {
            int l = 0;
            int r = rborder;

            while (l < r) {
                int mid = (l + r + 1) >> 1;

                if (taos2[i][1] >= taos1[mid][0]) {
                    l = mid;
                } else {
                    l = mid + 1;
                }
            }

            if (taos1[r][3] == taos2[i][3]) {
                r--;
            }

            if (taos2[i][1] < taos1[r][0]) {
                break;
            }

            taos2[i][1] -= taos1[r][0];
            rborder = r - 1;
        }

        for (int i = 0; i < n; i++) {
            res += (long) taos2[i][1] * taos2[i][2];
        }

        System.out.println(res);
    }
}

#美团笔试##美团实习#
全部评论
Mark
点赞 回复 分享
发布于 2024-03-25 23:38 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 23:27 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 23:16 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 23:01 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 22:49 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 22:42 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 22:26 江苏
Mark
点赞 回复 分享
发布于 2024-03-25 21:55 江苏
大佬,有兴趣投递淘天集团吗?我们服务供应链团队,负责天猫的增值服务相关的内容,实习刚开hc多多!
点赞 回复 分享
发布于 2024-03-20 22:42 浙江

相关推荐

不愿透露姓名的神秘牛友
07-23 18:25
点赞 评论 收藏
分享
码农索隆:竞争压力小,就你一个不用卷
点赞 评论 收藏
分享
评论
12
30
分享

创作者周榜

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