8.23秋招腾讯后台&综合开发笔试题解

8.23腾讯后台&综合开发笔试题解

Problem A

题意

给一个长度为n的链表,挖掉第k个元素,问挖掉元素后的序列。

做法

其实可以拿个数组存,下标为k不输出就可以了,代码也很短。

AC代码

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

const int N = 1e6 + 7;
int a[N];
int main() {
    int n, m; scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++)if(i != m)printf("%d ", a[i]);
    return 0;
}

Problem B

题意

给一个长度为n(n在5000内)的字符串,问字典序第k(k在5以内)小的子串是什么。

做法

k长度只有5,那答案的长度也不会超过5,只要把长度为5以内的所有子串抠出来排个序就可以了,AC代码中开了个set。

AC代码

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

int main() {
    set<string> s;
    string str;
    cin >> str;
    int n = str.length();
    for(int i = 0; i < n; i++) {
        string tmp;
        for(int j = 0; j < 5; j++)if(i + j < n) {
            tmp += str[i + j];
            s.insert(tmp);
        }
    }
    set<string>::iterator it = s.begin();
    int k; cin >> k;
    while(--k)it++;
    cout << *it << endl;
    return 0;
}

Problem C

题意

给一个数n,把它拆成a+b=n,要求a和b的数位和最大,求这个数位和。

做法

可以很容易想到一种贪心的方法,假设n是个x位数,那么我们可以让a为x-1个9组成的数,b为n-a。这个也比较容易想到以及证明。

AC代码

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

ll solve(ll n) {
    ll sum = 0;
    while(n) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}
int main() {
    int T; scanf("%d", &T); while(T--) {
        ll n; scanf("%lld", &n);
        ll a = 0;
        while(a <= n)a = a * 10 + 9;
        a /= 10;
        cout << solve(a) + solve(n - a) << endl;
    }
    return 0;
}

Problem D

题意

有n(n在5000内)块木板,宽度是1,长度不固定,这些小木板拼接起来一块大木板。

给一个宽度为1的刷子,每刷一次可以选择横着刷和竖着刷,过程中都不能离开木板。

问最少要刷几次能把木板完全刷一遍。

做法

动态规划题,表示当前完全刷完了前块木板,横着刷的部分能延伸到之后木板的部分高度为的最小代价,显然不会超过,因为所有木板竖着刷答案就是了,不存在横着刷高度超过的情况。

我们枚举所有的状态,转移情况如下:

  1. 竖着刷

    此时代价是1,能延伸的部分是和当前木板高度取最小值。

  2. 横着刷

    如果当前木板高度小于,则没有代价,否则要补上他们之间的差值,能延伸的部分是当前木板的高度。

AC代码

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

const int N = 5e3 + 7;
int dp[N][N];
int a[N];
int main() {
    memset(dp, 0x3f, sizeof dp);
    dp[0][0] = 0;
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
    for(int i = 0; i < n; i++)for(int j = 0; j <= n; j++) {
        int high;
        //竖着刷
        high = min(j, a[i + 1]);
        dp[i + 1][high] = min(dp[i + 1][high], dp[i][j] + 1);
        //横着刷
        if(a[i + 1] < n) {
            if(j >= a[i + 1])dp[i + 1][a[i + 1]] = min(dp[i + 1][a[i + 1]], dp[i][j]);
            else dp[i + 1][a[i + 1]] = min(dp[i + 1][a[i + 1]], dp[i][j] + a[i + 1] - j);
        }
    }
    int ans = n;
    for(int i = 0; i <= n; i++)ans = min(dp[n][i], ans);
    printf("%d\n", ans);
    return 0;
}

Problem E

题意

给定一个字符串,再给出若干个询问,问对应的子串最少可以由多少个回文串拼接而成。

做法

动态规划题再放送,表示区间的子串最少可以由多少个回文串拼接而成。

那么如果区间本身是回文串,就是1,否则我们枚举分割点x,计算 + ,在其中取一个最小,这是个经典区间dp的题目,转移先枚举区间长度(很显然转移方向是区间短的往区间长的转移),再枚举左端点,再枚举分割点。

最后对于所有的询问,直接访问dp数组下标输出即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N = 400 + 7;
char str[N];
int dp[N][N];
int main() {
    memset(dp, 0x3f, sizeof dp);
    scanf("%s", str + 1);
    int n = strlen(str + 1);
    for(int i = 1; i <= n; i++) {
        int l = i, r = i;
        while(1) {
            dp[l][r] = 1;
            l--, r++;
            if(l <= 0 || r > n)break;
            if(str[l] != str[r])break;
        }
    }
    for(int i = 1; i < n; i++) {
        int l = i, r = i + 1;
        if(str[l] != str[r])continue;
        while(1) {
            dp[l][r] = 1;
            l--, r++;
            if(l <= 0 || r > n)break;
            if(str[l] != str[r])break;
        }
    }
    for(int len = 1; len < n; len++)for(int i = 1; i <= n - len; i++) {
        int l = i, r = i + len; 
        for(int j = l; j < r; j++)dp[l][r] = min(dp[l][r], dp[l][j] + dp[j + 1][r]);
    }
    int q; scanf("%d", &q); while(q--) {
        int l, r; scanf("%d%d", &l, &r);
        printf("%d\n", dp[l][r]);
    }
    return 0;
}
#腾讯笔试##笔经##腾讯##C++工程师#
全部评论
AK了
4 回复 分享
发布于 2020-08-23 22:04
生而为人,我很抱歉
3 回复 分享
发布于 2020-08-23 22:53
楼主全ac了?这么强
2 回复 分享
发布于 2020-08-23 22:04
第三题一模一样,自测数据也都对,提交就是0,郁闷
1 回复 分享
发布于 2020-08-24 06:13
第四题没搞懂,有人解释一下嘛?
点赞 回复 分享
发布于 2020-08-25 11:04
java就离谱,一直超时
点赞 回复 分享
发布于 2020-08-24 15:17
请问为什么k长度只有5,那答案的长度也不会超过5呀??
点赞 回复 分享
发布于 2020-08-24 13:02
楼主,你第四定义N = 5e3 + 7,最后这个+7我没理解。能解释一下吗?
点赞 回复 分享
发布于 2020-08-24 04:38
恐怖如斯
点赞 回复 分享
发布于 2020-08-24 01:36
太强了!学习
点赞 回复 分享
发布于 2020-08-24 01:31
太厉害了
点赞 回复 分享
发布于 2020-08-23 22:33
楼主无敌
点赞 回复 分享
发布于 2020-08-23 22:17
第一题,我读取之后也是跳过第k个不输出,这么简单的过程,为什么说我超时啊?然后我也不存,就直接读取一个就输出,但是第k-1个不输出,还是说我超时,结果也就只过了75%。我实在是不明白,明明就是简单读取了输入都判我超时。我是Java。有没有人知道我这是咋回事啊?求解答
点赞 回复 分享
发布于 2020-08-23 22:16
点赞 回复 分享
发布于 2020-08-23 22:16
第一题还能这样。。。大佬太强了,用链表爆内存,哭了
点赞 回复 分享
发布于 2020-08-23 22:15
这也太强了吧
点赞 回复 分享
发布于 2020-08-23 22:11
🐂🍺
点赞 回复 分享
发布于 2020-08-23 22:09

相关推荐

bg双非本科,方向是嵌入式。这次秋招一共拿到了&nbsp;8&nbsp;个&nbsp;offer,最高年包&nbsp;40w,中间也有一段在海康的实习经历,还有几次国家级竞赛。写这篇不是想证明什么,只是想把自己走过的这条路,尽量讲清楚一点,给同样背景的人一个参考。一、我一开始也很迷茫刚决定走嵌入式的时候,其实并没有一个特别清晰的规划。网上的信息很零散,有人说一定要懂底层,有人说项目更重要,也有人建议直接转方向。很多时候都是在怀疑:1.自己这种背景到底有没有机会2.现在学的东西到底有没有用3.是不是已经开始晚了这些问题,我当时一个都没答案。二、现在回头看,我主要做对了这几件事第一,方向尽早确定,但不把自己锁死。我比较早就确定了嵌入式这个大方向,但具体做哪一块,是在项目、竞赛和实习中慢慢调整的,而不是一开始就给自己下结论。第二,用项目和竞赛去“证明能力”,而不是堆技术名词。我不会刻意追求学得多全面,而是确保自己参与的每个项目,都能讲清楚:我负责了什么、遇到了什么问题、最后是怎么解决的。第三,尽早接触真实的工程环境。在海康实习的那段时间,对我触动挺大的。我开始意识到,企业更看重的是代码结构、逻辑清晰度,以及你能不能把事情说清楚,而不只是会不会某个知识点。第四,把秋招当成一个需要长期迭代的过程。简历不是一次写完的,面试表现也不是一次就到位的。我会在每次面试后复盘哪些问题没答好,再针对性补。三、我踩过的一些坑现在看也挺典型的:1.一开始在底层细节上纠结太久,投入产出比不高2.做过项目,但前期不会总结,导致面试表达吃亏3.早期有点害怕面试,准备不充分就去投这些弯路走过之后,才慢慢找到节奏。四、给和我背景相似的人一点建议如果你也是双非,准备走嵌入式,我觉得有几件事挺重要的:1.不用等“准备得差不多了”再投2.项目一定要能讲清楚,而不是做完就算3.不要只盯着技术,多关注表达和逻辑很多时候,差的不是能力,而是呈现方式。五、写在最后这篇总结不是标准答案,只是我个人的一次复盘。后面我会陆续把自己在嵌入式学习、竞赛、实习和秋招中的一些真实经验拆开来讲,希望能对后来的人有点帮助。如果你正好也在这条路上,希望你能少走一点弯路。
点赞 评论 收藏
分享
评论
37
103
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务