字节 5.6 笔试题解(AK)

T1 简单模拟

#include <bits/stdc++.h>

using namespace std;

#define maxn 1000005

int n;
int tt[maxn], du[maxn];

int main() {
   cin >> n;
   for (int i = 0; i < n; ++i) {
       cin >> tt[i];
   }
   for (int i = 0; i < n; ++i) {
       cin >> du[i];
   }
   int st = 0, last = 0;
   int ans = 0;
   for (int i = 0; i < n; ++i) {
       if (tt[i] >= last) {
           ans += last - st;
           st = tt[i];
           last = st + du[i];
       } else {
           last = max(last, tt[i] + du[i]);
       }
   }
   ans += last - st;
   cout << ans << endl;
   return 0;
}

T2 数字的前缀

我们只需要判断一个数字是否是另外一个数字的前缀。因此我们记录前缀然后依次判断即可。
这里最好的做法是用字典树:
#include <bits/stdc++.h>

using namespace std;

#define maxn 1000005

int n;
vector<string> num;
int trie[maxn][10];
int no;

void add(string& s) {
    int p = 0;
    for (auto c : s) {
        if (trie[p][c-'0'] == 0) trie[p][c-'0'] = ++no;
        p = trie[p][c-'0'];
    }    
}

bool query(string& s) {
    int p = 0;
    for (auto c : s) {
        if (trie[p][c-'0'] == 0) return false;
        p = trie[p][c-'0'];
    }
    return true;
}

int main() {
    cin >> n;
    long long aa;
    bool ans = 0;
    for (int i = 0; i < n; ++i) {
        cin >> aa;
        num.push_back(to_string(aa));
    }
    sort(num.begin(), num.end(), [](string& a, string& b) {
        return a.size() > b.size();
    });
    for (int i = 0; i < n; ++i) {
        if (query(num[i])) {
            ans = 1;
            break;
        }
        add(num[i]);
    }
    if (ans) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}



T3 选择两个任务的最大价值

我们只需要选择两个任务,因此我们可以选择一个然后枚举另外一个物品即可。由于任务的时间是递增的,我们考虑从后往前枚举,如果我们选择了第 j 个任务,那么剩下的时间为 r = m - time[j], 因此我们只需要找到完成时间小于等于 r 的任务 i,那么 0~i 的任务都可以完成;此时最大的价值为:value[j] + pre[i] (pre[i] 表示前 i 个任务中最大的价值)。
#include <bits/stdc++.h>

using namespace std;

#define maxn 1000005

int n, m;
int tt[maxn], vv[maxn], pre[maxn];
int main() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        cin >> tt[i] >> vv[i];
    }
    pre[0] = 0;
    for (int i = 0; i < n; ++i) {
        pre[i+1] = max(pre[i], vv[i]);
    }
    int ans = 0;
    for (int j = n-1; j; --j) {
        int i = upper_bound(tt, tt+j, m - tt[j]) - tt;
        if (i > 0) {
            ans = max(ans, vv[j] + pre[i]);
        }
    }
    cout << ans << endl;
    return 0;
}

T4 最长连续上升子数组

我们需要考虑任何两段连续的递增数组组成的最大递增长度。

#include <bits/stdc++.h>

using namespace std;

#define maxn 1000005
int n;
int arr[maxn];
int len[maxn];
int no;
unordered_map<int, int> mmap;
int lowbit(int x) {
    return x&-x;
}

void add(int x, int v) {
    while (x <= no) {
        len[x] = max(len[x], v);
        x += lowbit(x);
    }
}

int query(int x) { 
    int ans = 0;
    while (x) {
        ans = max(ans, len[x]);
        x -= lowbit(x);
    }
    return ans;
}

int solve() {
    if (n <= 0) return 0;
    int i = 0, j = 1;
    int ans = 1;
    vector<int> qq;
    qq.push_back(query(1));
    while (j < n) {
        if (arr[j] <= arr[j-1]) { // 递减
            for (int k = i; k < j; ++k) {
                ans = max(ans, qq[k-i] + j - k);
            }
            qq.clear();
            int st = i;
            while (i < j) {
                add(arr[i], i - st + 1);
                ++i;
            }
            qq.push_back(query(arr[j]-1));
        } else { // 递增
            int t = query(arr[j]-1);
            qq.push_back(t);
            ans = max(ans, j - i + 1);
        }
        ++j;
    }
    for (int k = i; k < j; ++k) {
        ans = max(ans, qq[k-i] + j - k);
    }
    return ans;
}

int main() {
    cin >> n;
    vector<int> data;
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
        data.push_back(arr[i]);
    }
    sort(data.begin(), data.end());
    for (auto e : data) {
        if (!mmap.count(e)) mmap[e] = ++no;
    }
    for (int i = 0; i < n; ++i) {
        arr[i] = mmap[arr[i]];
    }
    cout << solve() << endl;
}


#春招##实习##笔试题目##面经#
全部评论
有全部的题解吗😀😀😀😀第一题给我整懵了
2 回复 分享
发布于 2022-05-06 12:07
有收到面试邀请的吗
1 回复 分享
发布于 2022-05-07 20:57
有没有测开笔试完,进面试了
1 回复 分享
发布于 2022-05-07 11:14
点赞 回复 分享
发布于 2022-05-06 12:09
楼主能讲一下第四题的思路吗,太菜了看不懂代码😭
点赞 回复 分享
发布于 2022-05-13 20:41
有算法的收到面试了吗
点赞 回复 分享
发布于 2022-05-09 08:37
T3在leetcode或牛客有相似的题吗
点赞 回复 分享
发布于 2022-05-08 21:42
想问一下第三题,我先根据价值降序排,再从头开始遍历,找到第一组在时间内的即为答案,为什么55%,也没有显示超时
点赞 回复 分享
发布于 2022-05-07 16:42
请问这是暑期实习的笔试吗
点赞 回复 分享
发布于 2022-05-07 11:19
T2用substr做得,,为啥只AC了83%
点赞 回复 分享
发布于 2022-05-07 11:07
第三题我还以为是0/1背包问题?结果背包问题的实现细节都给忘了
点赞 回复 分享
发布于 2022-05-06 23:19
我也做了,现在还有hc吗
点赞 回复 分享
发布于 2022-05-06 19:22
楼主投的哪里呀
点赞 回复 分享
发布于 2022-05-06 18:48
还是t2最简单了……
点赞 回复 分享
发布于 2022-05-06 17:53
我t3思路出问题了…… 用树状数组调了半天,结果被卡了输入,过了90%,和ak失之交臂😭
点赞 回复 分享
发布于 2022-05-06 15:26
第一题思路一样就是主循环里有点差异,只过了2/3。能帮忙看下吗    for (int i = 0; i < n; ++i) {        if (tt[i] >= last) {            ans += last - st;            st = tt[i];        }        last = max(last, tt[i] + du[i]);    }
点赞 回复 分享
发布于 2022-05-06 15:04
点赞 回复 分享
发布于 2022-05-06 14:18
蹲一个
点赞 回复 分享
发布于 2022-05-06 12:55
t4要用树状数组么…t3是什么思路,可以贪心不
点赞 回复 分享
发布于 2022-05-06 12:12

相关推荐

小浪_Coding:个人技能一条测试没有
点赞 评论 收藏
分享
练习JAVA时长两年半:qps 30000
点赞 评论 收藏
分享
评论
21
64
分享

创作者周榜

更多
牛客网
牛客企业服务