字节 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; }
#春招##实习##笔试题目##面经#