10.15 百度笔试

投了两个月,终于给我发笔试了,感觉也是海笔,随便做做吧

  1. 整数1~n,选择k个,计算最多可以获得多少积分。计分规则:若选择了i,并且没有选择i+1,积分加1

    分类讨论,如果 k > (n+1)/2,即返回 k(只选奇数)

    否则返回 n+1-k(前n-k个偶数不选,保证前n-k个奇数和n被算到积分当中)

    注意开 long long

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

int main() {
    int t;
    cin >> t;
    while (t--) {
        long long n, k;
        cin >> n >> k;
        if (k <= (n+1)/2) cout << k << endl;
        else cout << n+1-k << endl;
    }
    return 0;
}
  1. 一个长为n的字符串s,进行n次操作,第i次操作将 移动到字符串末尾,输出结果字符串

    用队列模拟。每次取出队列的前两个字符,第一个字符添加到队列尾,第二个字符输出

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

int main() {
    string s; 
    cin >> s;
    int n = s.size(), idx = 0;
    while (n--) {
        s.push_back(s[idx++]);
        cout << s[idx++];
    }
    return 0;
}
  1. 长为n的数组a,每次交替在数字中写下加减符号,求最后剩余的数字(对 1e9 + 7 取模)

    例如:[1,2,3,4] -> [1+2, 2-3, 3+4] = [3, -1, 7] -> [3-(-1), -1+7] = [4, 6] -> [4-6] = [-2],取模后输出 1e9 + 5

    只需要计算每个下标的数字在最后的结果中所占的权值即可

    找规律发现,n=4k+1 时最后的权值与杨辉三角有关,于是其他的情况统统归到 4k+1 即可。(应该有比较严格的数学解法)

    (n=5 时,各个位置的权重为 1 0 2 0 1,n=9 时,各个位置的权重为 1 0 4 0 6 0 4 0 1)

#include <iostream>
#include <bits/stdc++.h>
#include <vector>
using namespace std;
using ll = long long;

const int mod = 1e9 + 7;

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

int main() {
    int n;
    cin >> n;
    vector<ll> a(n);
    for (auto & x : a) cin >> x;

    vector<ll> fact(n+1), inv(n+1);
    fact[0] = 1;
    for (int i = 1; i <= n; i++) fact[i] = fact[i-1] * i % mod;
    inv[n] = qpow(fact[n], mod-2);
    for (int i = n-1; i >= 0; i--) inv[i] = inv[i+1] * (i+1) % mod;

    auto C = [&](int x, int y) {
        return fact[x] * inv[y] % mod * inv[x-y] % mod;
    };

    int k = (n - 1) / 4 * 2 + 1;
    vector<ll> t(2 * k + 1, 0);
    for (int i = 1; i <= k; i++) t[2*i-2] = C(k-1, i-1);

    bool flag = true; // + or -
    while (n % 4 != 1) {
        n--;
        vector<ll> a2(n);
        for (int i = 0; i < n; i++) {
            a2[i] = (a[i] + (flag ? 1 : -1) * a[i+1] + mod) % mod;
            flag = !flag;
        }
        a = move(a2);
    }
    
    ll ans = 0;
    for (int i = 0; i < n; i++) {
        ans = (ans + a[i] * t[i] % mod) % mod;
    }
    cout << ans << '\n';
    return 0;
}
#软件开发笔面经##百度#
全部评论
太牛了哥🐮,第二题我也发现了这个规律,但是还是很笨b的用双链表模拟的,每次取next next,就是没想到能直接用队列这么简单秒了
5 回复 分享
发布于 10-15 22:56 江苏
第二题 可以直接从第二个字符开始 隔一个取一个 非常简单的思路
3 回复 分享
发布于 10-16 15:03 广东
大佬,第二题可以这样做的原因是啥
2 回复 分享
发布于 10-15 22:31 北京
大佬真的太强了,第三题我想了很久都没想出来。不过第二题我用链表做的,比较朴素,没大佬这么简洁
1 回复 分享
发布于 10-15 23:25 上海
太优雅了
1 回复 分享
发布于 10-16 00:03 河南
没笔,发面试了 怎么办,后面还有笔试机会吗
1 回复 分享
发布于 10-17 10:55 北京
牛皮,第三题,弄半天一直超时。
点赞 回复 分享
发布于 10-15 22:38 重庆
为啥我第三题是打麻将胡牌啊😂
点赞 回复 分享
发布于 10-15 23:22 北京
牛的,第三题暴力了20%后看了眼时间果断交卷了,不折磨自己
点赞 回复 分享
发布于 10-16 08:42 江苏
牛的
点赞 回复 分享
发布于 10-16 10:42 湖北
忘记做了
点赞 回复 分享
发布于 10-16 13:15 上海
第一题死活过不去害,后面两题超时,寄了
点赞 回复 分享
发布于 10-16 15:38 江西
大佬第三题只过80%是为什么啊,头都看烂了
点赞 回复 分享
发布于 10-16 18:58 江苏
第二题我用substr函数做的,就是超时了
点赞 回复 分享
发布于 10-16 23:51 上海
太强了大佬,第二题暴力只过了73%,想到取第二个数之后没想到用队列做就到时间了
点赞 回复 分享
发布于 10-17 01:02 广东
熟悉的a批码风
点赞 回复 分享
发布于 10-18 16:21 北京

相关推荐

10-29 15:01
门头沟学院 Java
比亚迪 新技术院 30w+
爱吃肉的猪猪吃不饱:签笛子等华为和荣耀
点赞 评论 收藏
分享
34 48 评论
分享
牛客网
牛客企业服务