美团春招第一轮笔试题,只通过3.45,好难。。。

只通过了3.45.。。。。搞不懂啊。。。希望大佬们可以补充,指点下。。

美团 0312 笔试

1. 两行长度均为 n 字符串,仅包含字符'X`(代表障碍物)和'.'(可以通行),初始在左上角(1, 1),想到右下角(2, n)去,求方案数,如果不能到(2, n) 输出-1。数据范围:

通过 45%,搞不懂。

#include <bits/stdc++.h>
using namespace std;

int n;
long long dp[2][5500];
string str[2];

int main() {
    cin >> n;
    cin >> str[0] >> str[1];
    if (str[0][0] == 'X') {
        cout << -1 << endl;
        return 0;
    }
    dp[0][0] = 1;
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < 2; ++j)if (str[j][i] == '.') {
            dp[j][i] = dp[j][i-1] + dp[j^1][i-1];
        }
    }
    if (dp[1][n-1] == 0) dp[1][n-1] = -1;
    cout << dp[1][n-1] << endl;
    return 0;
}

2. 一个包含 n 个元素的数组,每个元素值是[L, R]的范围内的,求满足 n 个元素之和是 k 的倍数的数组个数。数据范围:

用 dp[i][j] 表示和模 k 后是 j 的长度为 i 的数组个数。需要先算下[L, R] 中 模 k 后是 j 的数字个数:num[j] = (R-j)/k - (L-1-j)/k。时间复杂度:

代码没保存。100%通过。

3. 长度为 n 的数组和一个 x,可以让 x 和数组中任意数字或操作替代原来的数字,这个操作可以进行任意次。求最终数组众数的最大值。数据范围:

用 cnt[p]表示最终数组中数字 p 的数字个数。首先 cnt[data[i]]++,如果 data[i] != x,则 cnt[x | data[i]]++,最后遍历一遍 cnt 数组即可。

100%通过。

4. 一个 n 个节点 m 条无向边的图,保证图连通,第 i 个节点的标记是 id[i],想要从每个节点出发收集 k 种不同的 id,求每个节点需要的最短路径和。数据范围

思路:从 1 到 k 枚举每个 id,计算每个节点需要的路径长度。假设当前计算的 id 是 p,则把所有标记是 p 的节点放进队列里,然后 bfs 计算。时间复杂度:

只通过 55%,搞不懂。

#include <bits/stdc++.h>
using namespace std;

const int N = 100010, KK = 110;

int n, m, K;
int dp[N][KK], idx[N];
vector<int> G[N];

void solve(int k) {
    queue<int> Q;
    for (int i = 1; i <= n; ++i) if (idx[i] == k) {
        Q.push(i);
    }
    while (!Q.empty()) {
        int cur = Q.front(); Q.pop();
        for (auto v: G[cur]) if (dp[v][k] == 0x3f3f3f3f) {
            dp[v][k] = dp[cur][k] + 1;
            Q.push(v);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> K;
    for (int i = 1; i <= n; ++i) cin >> idx[i];
    for (int i = 0; i < m; ++i) {
        int u, v; cin >> u >> v;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }
    memset(dp, 0x3f, sizeof (dp));
    for (int i = 1; i <= n; ++i) dp[i][idx[i]] = 0;

    for (int k = 1; k <= K; ++k) {
        solve(k);
    }
    for (int i = 1; i <= n; ++i) {
        int sum = 0;
        for (int k = 1; k <= K; ++k) sum += dp[i][k];
        cout << sum << " \n"[i == n];
    }
    return 0;
}

5. 射击 n 次靶子,第 i 次命中靶心的概率是,求 n 次后只脱离靶心 0 次、1 次、2 次的概率分别是多少?把最终的概率写成最简分数形式,然后对 998244353 取模。数据范围

先算逆元,然后 dp 算一下。只通过了 45%,搞不懂。请赐教。

比较尴尬的是如果把下面的代码中double st = clock();double ed = clock() - st;不注释掉,那么会报 RE,通过率 0%,这就很尴尬了啊。。。平台有点搞不懂。

#include <bits/stdc++.h>
using namespace std;

const int N = 100010;
using ll = long long;
const ll mod = 998244353;

int n;
ll data[N], inv[N], inv2[N], dp[N][3];

ll Qpow(ll a, ll b) {
    ll ret = 1;
    while (b) {
        if (b & 1) ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret;
}

int main() {
    ios_base::sync_with_stdio(0);
    // double st = clock();
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> data[i];
        inv[i] = Qpow(data[i], mod-2);
        inv2[i] = (data[i] - 1) * inv[i] % mod;
    }
    dp[1][0] = inv[1];
    dp[1][1] = inv2[1];
    for (int i = 2; i <= n; ++i) {
        dp[i][0] = dp[i-1][0] * inv[i] % mod;
        dp[i][1] = (dp[i-1][0] * inv2[i] % mod + dp[i-1][1] * inv[i] % mod) % mod;
        dp[i][2] = (dp[i-1][1] * inv2[i] % mod + dp[i-1][2] * inv[i] % mod) % mod;
    }
    cout << dp[n][0] << " " << dp[n][1] << " " << dp[n][2] << endl;
    // double ed = clock() - st;
   // printf("time=%.3f\n", ed / CLOCKS_PER_SEC);
    return 0;
}
#美团笔试题##美团##笔试题目#
全部评论
最后一题我逆元也是45…
2 回复 分享
发布于 2020-03-12 21:47
吊打20届
1 回复 分享
发布于 2020-03-12 23:22
楼主 估计银牌水平往上了吧
点赞 回复 分享
发布于 2020-03-25 09:52
求教大佬,怎么感觉第二题的时间复杂度为O(N*K*K)呢
点赞 回复 分享
发布于 2020-03-24 22:43
public int getMax(String[][] str){         int r = str.length,c = str[0].length;         int dp[][] = new int[r][c];         if(str[0][0] == "X") return -1;          dp[0][0] = 1;         if(str[1][0] == ".") dp[1][0] = 1;         for(int j = 1;j<c;j++){             for(int i = 0;i<2;i++){                 if(str[i][j] == "."){                     dp[i][j] += str[i^1][j] == "."?dp[i^1][j-1]:0;                     dp[i][j] += dp[i][j-1];                 }else{                     dp[i][j] = 0;                 }             }         }         return dp[1][c-1] == 0?-1:dp[1][c-1];     }
点赞 回复 分享
发布于 2020-03-23 22:51
这就是强者的口吻,既然都写出来了
点赞 回复 分享
发布于 2020-03-21 17:48
老哥是本科还是研究生?
点赞 回复 分享
发布于 2020-03-21 10:13
tql
点赞 回复 分享
发布于 2020-03-21 09:59
请问楼主笔试算法全是编程题吗
点赞 回复 分享
发布于 2020-03-18 15:31
笔试算法这么多题吗
点赞 回复 分享
发布于 2020-03-17 16:03
求教第二题
点赞 回复 分享
发布于 2020-03-17 15:57
收到面试通知了吗?
点赞 回复 分享
发布于 2020-03-13 11:49
真的大佬,太强了
点赞 回复 分享
发布于 2020-03-13 10:05
已经很强了
点赞 回复 分享
发布于 2020-03-12 22:43
第一题为什么数组开5500啊 😂我就开到51 才过18%。。。
点赞 回复 分享
发布于 2020-03-12 22:39
我也是
点赞 回复 分享
发布于 2020-03-12 21:49

相关推荐

04-27 08:59
常州大学 Java
牛客139242382号:《两门以上汇编语言》
点赞 评论 收藏
分享
03-26 15:18
已编辑
华北水利水电大学 Java
点赞 评论 收藏
分享
评论
12
103
分享

创作者周榜

更多
牛客网
牛客企业服务