首页 > 美团4.4笔试题解
头像
程勇201921010625
编辑于 2021-04-18 13:35
+ 关注

美团4.4笔试题解

早起做了一个小时,除了第二题没得全分(后来发现是没有特殊考虑没有切精度的情况,***了),其他都ac了。

第一题

脑经急转弯,统计出每个字符出现次数,答案就是各个字符出现次数+1的累乘。注意每一步都要取模,且中间过程可能会爆int,最后用long long存,不然需要对中间过程强转一下,代码如下:

#include <iostream>
using namespace std;

const int MOD = 20210101;
int num[26];
int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    string s; cin >> s;
    for(char c: s) num[c - 'a'] ++ ;
    long long res = 1;
    for(int i = 0; i < 26; i ++ ){
        res = res * (num[i] + 1) % MOD;
    }
    cout << res << endl;
    return 0;
}

第二题

没得全分就不贴代码了。。。

第三题

暴力即可,找出每个数的所有约数,这个计算时间复杂度为,总共有20w个数,每个数最大为2w,故最多计算2000w+次,可以过。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    string t = to_string(k);
    int res = 0;
    for(int i = 0; i < n; i ++ ){
        int a; cin >> a;
        vector<int> f;
        for(int j = 1; j * j <= a; j ++ ){
            if(a % j == 0){
                f.push_back(j);
                if(a / j != j) f.push_back(a / j);
            }
        }
        sort(f.begin(), f.end());
        string s;
        for(int num: f) s += to_string(num);

        int index = s.find(t);
        if(index >= 0 && index < s.size()) res ++ ;
    }
    cout << res << endl;
    return 0;
}

第四题

简单dp,用记忆化搜索写起来更简单,因为数据量只有50,无需优化,写了个的dfs,如下:dfs(x,y)表示从1跳到g[x][y]对应的数字最少花费是多少,显然dfs(x,y)=min(dfs(i,j)+abs(x-i)+abs(y-j)),(i,j)满足(g[i][j]+1=g[x][y])

#include <iostream>
#include <set>
#include <cstring>
using namespace std;

const int N = 55;
int g[N][N];
int dp[N][N];
int n, k; 
void dfs(int x, int y){
    if(dp[x][y] != -1) return;
    if(g[x][y] == 1) {
        dp[x][y] = 0;
        return;
    }
    int t = g[x][y] - 1;
    int ret = 1e9;
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= n; j ++ ){
            if(g[i][j] == t){
                int d = max(x - i, i - x) + max(y - j, j - y);
                dfs(i, j);
                ret = min(ret, dp[i][j] + d);
            }
        }
    dp[x][y] = ret;
}
int main(int argc, char const *argv[])
{
    cin >> n >> k;
    set<int> st;
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= n; j ++ ){
            cin >> g[i][j];
            if(g[i][j] >= 1 && g[i][j] <= k)
                st.insert(g[i][j]);
        }
    if(st.size() != k){
        cout << -1 << endl;
        return 0;
    }
    int res = 1e9;
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= n; j ++ ){
            if(g[i][j] == k) {
                memset(dp, -1, sizeof dp);
                dfs(i, j);
                res = min(res, dp[i][j]);
            }
        }
    cout << res << endl;
    return 0;
}

专项题

这个没啥说的,求一个数组前k项,这k项之和最大,前缀和即可:

#include <iostream>
using namespace std;

const int N = 200001;
int a[N], b[N];
int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    int m, n; cin >> m >> n;
    int res = 0, t1 = 0, t2 = 0;
    for(int i = 0; i < m; i ++ ){
        int x; cin >> x;
        a[i + 1] = a[i] + x;
        t1 = max(t1, a[i + 1]);
    }
    for(int i = 0; i < n; i ++ ){
        int x; cin >> x;
        b[i + 1] = b[i] + x;
        t2 = max(t2, b[i + 1]);
    }
    res = t1 + t2;
    cout << res << endl;
    return 0;
}

全部评论

(11) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

热门推荐