美团8月20日 全AK代码

1. 两个字符串循环插入

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n;
    cin >> n;
    string A, B;
    cin >> A >> B;
    string res = "";
    for (int i = 0; i < n; i++)
    {
        res = res + A[i] + B[i];
    }
    cout << res << endl;
    return 0;
}

2. 已知三个点(x1,y1), (x2, y2), (x3, y3)的坐标,以及三个点到目标(a,b)点的曼哈顿距离d1,d2,d3 求,(a,b)字典序的最小值

思路:正常可以通过2次循环模拟,但是会超时,可以将abs(y-b)的值存储起来,然后在遍历abs(x-a) 查看 abs(y-b)是否对应同一个b即可
#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int x1, y1, x2, y2, x3, y3;
    cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
    int d1, d2, d3;
    cin >> d1 >> d2 >> d3;
    int a, b;
    unordered_map<int, unordered_map<int, bool>> ymap1;
    unordered_map<int, unordered_map<int, bool>> ymap2;
    unordered_map<int, unordered_map<int, bool>> ymap3;
    for (int i = 1; i <= n; i++)
    {
        ymap1[abs(y1 - i)][i] = true;
        ymap2[abs(y2 - i)][i] = true;
        ymap3[abs(y3 - i)][i] = true;
    }
    for (int i = 1; i <= n; i++)
    {

        if (ymap1.count(d1 - abs(x1 - i)) > 0 &&
            ymap2.count(d2 - abs(x2 - i)) > 0 && ymap3.count(d3 - abs(x3 - i)) > 0)
        {
            int j = -1;
            for (auto &s : ymap1[d1 - abs(x1 - i)])
            {
                if (ymap2[d2 - abs(x2 - i)][s.first] &&
                    ymap3[d3 - abs(x3 - i)][s.first])
                {
                    j = s.first;
                    break;
                }
            }
            if (j == -1)
                continue;
            a = i;
            b = j;
            cout << a << " " << b << endl;
            return 0;
        }
    }
    return 0;
}

3. 已值n个题目,每个题目得分为有p / 100的概率得到val的分数,1 - p/100得分为0,然后可以选择m个进行复习,把概率提升到100%,问最多可以获得多少分

思路:每个题可以获得如果提升到100%然后提升的分数(1- p/100) * val,然后对该提高的分数排序即可,对前m个进行分数提高剩下的不变,则是最高分数(注意有精度要求,把所有的变量定位double,否则通过不了
#include <bits/stdc++.h>

using namespace std;

struct node
{
    double p;
    double val;
    double add;
};
bool cmp(struct node &a, struct node &b)
{
    return a.add > b.add;
}
int main()
{
    int n, m;
    cin >> n >> m;
    vector<node> vals(n);
    for (int i = 0; i < n; i++)
    {
        double p;
        cin >> p;
        vals[i].p = p / 100.0;
    }
    for (int i = 0; i < n; i++)
    {
        cin >> vals[i].val;
        vals[i].add = (1.0 - vals[i].p) * vals[i].val;
    }
    sort(vals.begin(), vals.end(), cmp);
    double res = 0;
    for (int i = 0; i < n; i++)
    {
        if (i < m)
            res += vals[i].val;
        else
            res += vals[i].p * vals[i].val;
    }
    printf("%.2f", res);
    return 0;
}

4. 有两个队列A, B,可以对A或者B中的一个值进行变换,一种是将值给消除,代价为|a|,一种是将值变成另外一个数,代价为|b-a|,请问将A,B变成相同数列的最小代价

思路: leetcode编辑距离的变形
#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, m;
    cin >> n >> m;
    vector<int> A(n);
    vector<int> B(m);
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    for (int i = 0; i < n; i++)
    {
        cin >> A[i];
        dp[i + 1][0] += abs(A[i]) + dp[i][0];
    }
    for (int i = 0; i < m; i++)
    {
        cin >> B[i];
        dp[0][i + 1] += abs(B[i]) + dp[0][i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            dp[i][j] = min(dp[i - 1][j - 1] + abs(B[j - 1] - A[i - 1]),
                           dp[i - 1][j - 1] + abs(B[j - 1]) + abs(A[i - 1]));
            dp[i][j] = min(dp[i][j], min(dp[i][j - 1] + abs(B[j - 1]), dp[i - 1][j] + abs(A[i - 1])));
        }
    }
    cout << dp[n][m] << endl;
    return 0;
}

5. 有B,包含了一系列需要处理的材料b1,b2,b3,然后需要用A中的材料进行处理,满足 aij > b1,a中的元素可以无限使用,请问最少使用的A的材料是多少,不满足返回-1

思路:遍历B,排序A,然后二分查找A,时间复杂度 min(n,m) log2m
#include <bits/stdc++.h>

using namespace std;

int binarySearch(vector<int> &nums, int target)
{
    int l = 0, r = nums.size() - 1;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (nums[mid] == target)
        {
            return mid;
        }
        else if (nums[mid] < target)
        {
            l = mid + 1;
        }
        else
        {
            r = mid;
        }
    }
    return l;
}
int main()
{
    int n, m;
    cin >> n >> m;
    vector<int> B(n);
    vector<int> A(m);
    for (int i = 0; i < n; i++)
        cin >> B[i];
    for (int i = 0; i < m; i++)
        cin >> A[i];
    sort(A.begin(), A.end());
    long long res = 0;
    for (int i = 0; i < n; i++)
    {
        if (B[i] > A[m - 1])
        {
            cout << -1 << endl;
            return 0;
        }
        int idx = binarySearch(A, B[i]);
        res += A[idx];
    }
    cout << res << endl;
    return 0;
}



#美团笔试#
全部评论
第一题基本一模一样的做法,但是c++只有27%,请问大佬为啥呀
点赞 回复 分享
发布于 2022-08-27 18:15 北京
第二题有一个O(1)的做法,距离三个定位点距离为d1,d2,d3的构成三个菱形,只需要算两两的菱形交点,然后判断这个交点和第三个菱形有无交点,就可以得到一个候选点列表,根据棋盘大小,以及候选点坐标为整数筛掉不符合的。然后按字典序对候选点进行排序,输出最小的即可。
点赞 回复 分享
发布于 2022-08-21 21:38 北京
艹第四题写的一模一样我用python告诉我超时了…
点赞 回复 分享
发布于 2022-08-22 12:33 北京
第四题用例输出的答案不正确。。。
点赞 回复 分享
发布于 2022-08-22 16:21 湖南

相关推荐

不愿透露姓名的神秘牛友
11-27 10:48
点赞 评论 收藏
分享
Java抽象带篮子:难蚌,点进图片上面就是我的大头😆
点赞 评论 收藏
分享
牛客868257804号:九个中铁八个中建
点赞 评论 收藏
分享
评论
4
15
分享
牛客网
牛客企业服务