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

写一下2024年美团秋招第一场笔试算法题解,先贴个测评和题目链接美团2024秋招第一场笔试,还是比较简单的,前两题都是模拟,其中第二题涉及点思维,第三题笔者看到有牛友用持久化线段树和dp做的,但是我还不咋会主席树哈哈,于是给大家提供一种很巧妙的模拟做法,希望可以对大家有所帮助~~~(ak美团笔试题就可以去美团送外卖了)------不说了,我快超时了-----

最近开始开始重开java后端开发了,兜兜转转还是java选手,我打算以后多更新大厂算法笔试的题解~~~~欢迎大家讨论交流和支持,蟹蟹~~~

目录

A题

题面

思路分析

代码实现

B题

题面

思路分析

代码实现

C题

题面

思路分析

代码实现


A题

题面

思路分析

直接模拟就行,判断数字可以用isdigit函数,判断字母可以用alpha函数。

代码实现

cpp 复制代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long 
#define x first 
#define y second 
using namespace std;
int f(string s)
{
    int cnt1 = 0;
    int cnt2 = 0;
    int cnt3 = 0;
    //int flag = 0;
    for(int i = 1; i < s.size(); i++)
    {
        if(isdigit(s[i])) cnt1 ++;
        else if((s[i] >= 'a' && s[i] <= 'z')||(s[i] >= 'A' && s[i] <= 'Z')) cnt2 ++;
        else cnt3++;
    }
    if(cnt1 == s.size() - 1) return  1;
    else if(cnt2 == s.size() - 1) return 2;
    else if(cnt3 == 0) return 3;
    else return 4;
}
void solve()
{
    string s;
    cin >> s;
    if(isdigit(s[0]) && f(s) == 2) cout << "special" << endl;
    else if(isalpha(s[0]) && f(s) == 1) cout << "standard" << endl;
    else if(isalpha(s[0]) && f(s) == 3) cout << "mix" << endl; 
    else cout << "invalid" << endl;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t;
    cin >> t;
    while(t -- )  solve();
    return 0;
}

B题

题面

思路分析

做这题最开始笔者想歪了,开个map把每个字符串数量统计进去,然后开了个字符串数组还对字符串排个序 ,但是发现这样对解这道题一点用没有,于是仔细看看题目,我们梳理一下题意,题目让我们求最少和最多比较次数,首先我们应该明白最少操作次数为1,第二点重要的是一定是从比小于正确密码长度的字符串开始比较的,如果发现不匹配则再次碰到这样的字符串我们就不再比较,于是我们有如下思路:

1.开一个哈希表set,记录有没有添加过该密码,至少需要尝试1次

2.如果输入的密码长度小于真实密码且未出现过,一定会被尝试,两个都加一次

  1. //如果输入的密码长度等于真实密码且未出现过,最多的加一次就行了,因为算最少我们一次就能匹配成功,所以x不用加。

下面我们看看完整代码就明白了------

代码实现

cpp 复制代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cstring>
#include <string>
#include <vector>
#include <unordered_set>
#define int long long 
#define x first 
#define y second 
using namespace std;

void solve()
{
     int n;
     cin >> n;
     string str;
     cin >> str;
     unordered_set<string> st;//记录有没有添加过该密码
     int x = 1;//至少需要尝试1次
     int y = 0;
     while(n -- )
     {
        string s;
        cin >> s;
        //如果输入的密码长度小于真实密码且未出现过,一定会被尝试,两个都加一次
        if(s.size() < str.size() && st.count(s) == 0) 
        {
             x++;
             y++;
             st.insert(s);
        }
        //如果输入的密码长度等于真实密码且未出现过,最多的加一次就行了
        if(s.size() == str.size() && st.count(s) == 0) 
        {
            y++;
            st.insert(s);
        }
     }
     cout << x << " " << y << endl;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t = 1;
    while(t -- )  solve();
    return 0;
}

C题

题面

思路分析

这题笔者也不知道本题出题的std是什么,应该很多种做法,看到了可持久化线段树,dp等做法,但是大家好像大多还是模拟来做的,这里贴一种巧妙的做法,妙在反着去判断当前数组中不包含的最小非负整数,利用一个while循环和一个set容器,我们for循环倒着遍历,依次删除前j个元素,然后再将剩下的元素按照MEX(a) * k删除,MEX(a)就用set不断地insert剩下的每个元素,从最开始ans = 0维护,如果set里存入了后面的数,我们将ans++即可,最后跳出循环的ans即为剩下数组里不存在的最小非负整数,我在代码中把样例的x,j,k,ans都输出了,方便理解,仔细看看代码其实也就明白了,完成了上面操作,我们不断求花费值然后更新最小值就行了------

代码实现

cpp 复制代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <unordered_set>
#define int long long 
#define x first 
#define y second 
using namespace std;

void solve()
{
    int n,k,x;
    cin >> n >> k >> x;
    vector<int> vc(n);
    set<int> st;
    for(int i = 0; i < n; i++) cin >> vc[i];
    int minx = x * n;  // 依次删除第一个元素
    int ans = 0;
    //反着去判断当前数组中不包含的最小非负整数
    for(int j = n - 1; j >= 0; j--)
    {
        st.insert(vc[j]);
        while(st.count(ans)) 
        {
            ans++;
        }
        //依次删除前j个元素再将剩下的元素按照MEX(a) * k删除
        //cout << x << " " << j << " " << k << " " << ans << endl;
        int p = x * j + k * ans;
        //cout << p << endl;
        minx = min(minx , p);
    }
    cout << minx << endl;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t;
    cin >> t;
    while(t -- )  solve();
    return 0;
}
/*
    input:
    1
    6 3 3
    4 5 2 3 1 0
    output:
       3 5 3 1
       18
       3 4 3 2
       18
       3 3 3 2
       15
       3 2 3 4
       18
       3 1 3 4
       15
       3 0 3 6
       18
15(最小值)

*/

最后感谢大家的观看,点个赞加关注再走吧~~拜拜喽~

相关推荐
十五年专注C++开发7 分钟前
FlatBuffers: 一个高效的零拷贝二进制序列化库
c++·序列化·反序列化·flatbuffers
SL_staff18 分钟前
制造订单交付闭环实践:用跨部门计划模板解决缺料-停机-返工三角死循环
java·开源·产品
device_Any21 分钟前
接口文档写着三个字段,接口返回了五个
android·java·linux
CCblandy25 分钟前
缓存淘汰实测:一次全表扫描把 LRU 命中率从 46% 打到 38%,W-TinyLFU 守住 50% 却贵 11 倍
后端·python·缓存·性能优化·架构
Wang's Blog27 分钟前
Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存
java·缓存·交友
xys_67832 分钟前
深挖C++:C++入门基础
开发语言·c++
汤米粥33 分钟前
cmd手动创建的Django项目怎么用社区版Pycharm运行起来
python·pycharm·django
香蕉大香蕉(06敬畏市场)38 分钟前
MySQL 单点详解(09)
java·数据库·mysql·面试·八股·大厂实习
涵玥38 分钟前
python题目练习12-小玉家的电费//小玉在游泳//小鱼的航程
python·python每日一练·洛谷题目
计算机毕业编程指导师43 分钟前
基于深度学习的花卉图像分类识别系统(PyTorch + ResNet50 + Django)
pytorch·python·深度学习·分类·毕业设计·迁移学习·图像分类