介绍
豆包青训营是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目,主要面向在校大学生。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用。
课程内容和方向
豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习,
本文提供训练营试题解析供参考
试题1:贪心猫的鱼干大分配
问题描述:
在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:
每只猫至少得到一斤鱼干。
如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。
小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。
def solution(n, cats_levels):
# 初始化每只猫的鱼干数量为1
fish_amounts = [1] * n
# 从左到右遍历,确保每只猫的鱼干数量满足条件
for i in range(1, n):
if cats_levels[i] > cats_levels[i - 1]:
fish_amounts[i] = fish_amounts[i - 1] + 1
# 从右到左遍历,确保每只猫的鱼干数量满足条件
for i in range(n - 2, -1, -1):
if cats_levels[i] > cats_levels[i + 1]:
fish_amounts[i] = max(fish_amounts[i], fish_amounts[i + 1] + 1)
# 返回鱼干总数
return sum(fish_amounts)
if __name__ == "__main__":
# You can add more test cases here
cats_levels1 = [1, 2, 2]
cats_levels2 = [6, 5, 4, 3, 2, 16]
cats_levels3 = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
print(solution(3, cats_levels1) == 4)
print(solution(6, cats_levels2) == 17)
print(solution(20, cats_levels3) == 35)
试题2:最大相等分割红包金额
问题描述:
小U在公司年会上运气极佳,赢得了一等奖。作为一等奖得主,他有机会在一排红包中做两次切割,将红包分成三部分,要求第一部分和第三部分的红包总金额相等。他可以获得的金额是第一部分红包的总金额。帮小U计算出他能从这些红包中拿到的最大奖金金额。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include <functional>
using namespace std;
typedef long long ll;
int solution(std::vector<int> redpacks) {
// Please write your code here
int prefix[1001]={0};
int i=0,j=0,k=0,maxnum=0;
int t1,t2,t3;
for(i=0;i<redpacks.size();i++){
prefix[i+1]=prefix[i]+redpacks[i];
}
for(i=0;i<=redpacks.size();i++){
t1=prefix[i];
for(j=i;j<=redpacks.size();j++){
t2=prefix[j]-t1;
t3=prefix[redpacks.size()]-prefix[j];
if(t1==t3){
if(t1>maxnum){
maxnum=t1;
}
}
}
}
return maxnum;
}
int main() {
std::vector<int> redpacks1 = {1, 3, 4, 6, 7, 14};
std::vector<int> redpacks2 = {10000};
std::vector<int> redpacks3 = {52, 13, 61, 64, 42, 26, 4, 27, 25};
std::vector<int> redpacks4 = {2, 5, 50, 30, 60, 52, 26, 5, 74, 83, 34, 96, 6, 88, 94, 80, 64, 22, 97, 47, 46, 25, 24, 43, 76, 24, 2, 42, 51, 96, 97, 87, 47, 93, 11, 98, 41, 54, 18, 16, 11, 96, 34, 36, 87, 24, 32, 27, 62, 72, 54, 14, 67, 5, 21, 20, 44, 55, 3, 82, 19, 45, 1, 52, 14, 44, 46, 39, 83, 27, 30, 87, 61, 56, 59, 10, 83, 80, 42, 44, 75, 39, 43, 41, 23, 93, 73, 50, 94, 94, 82, 46, 87, 60, 94, 47, 52, 67, 22, 50, 49, 8, 9, 30, 62, 87, 13, 11};
std::cout << (solution(redpacks1) == 14) << std::endl;
std::cout << (solution(redpacks2) == 0) << std::endl;
std::cout << (solution(redpacks3) == 52) << std::endl;
std::cout << (solution(redpacks4) == 2627) << std::endl;
return 0;
}
试题3:RGB色值转换为整数值
问题描述:
小M需要一个函数,用于将RGB颜色值转换为相应的十六进制整数值。RGB色值以字符串的形式给出,如"rgb(192, 192, 192)",需要转换为对应的整数值。
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
int solution(std::string rgb) {
//去除 "rgb(" 和 ")",并用逗号分割字符串
std::string trimmed = rgb.substr(4, rgb.size() - 5);
std::istringstream iss(trimmed);
std::vector<int> values;
int value;
//读取每个颜色分量
while (getline(iss, trimmed, ',')) {
std::istringstream(trimmed) >> value;
values.push_back(value);
}
//计算十六进制颜色值
int hexValue = (values[0] << 16) | (values[1] << 8) | values[2];
return hexValue;
}
int main() {
// You can add more test cases here
std::cout << solution("rgb(192, 192, 192)") << std::endl;
std::cout << solution("rgb(100, 0, 252)") << std::endl;
std::cout << solution("rgb(33, 44, 55)") << std::endl;
return 0;
}
试题4:阿D的最佳飞行路线探索
问题描述:
小C和他的领导小F计划一次飞行,但由于严格的航空管制,他们的飞机仅能按特定的路线飞行:飞机只能飞往当前机场的相邻机场或相同航空公司管理的机场。为了减少起飞次数,小C需要制定最优的飞行路线。机场由一个数组airports标识,其中:
数组每个元素代表一个独特的机场,元素的值代表不同的航空公司。
airports[0]为起点,airports[airports.length - 1]为终点。
假设小C当前在机场i,那么i - 1和i + 1(如果存在)代表邻近机场,飞机可以直接前往。
如果在机场i,且存在airports[i] == airports[j],则机场i和机场j同属一家航空公司,可直接飞往。
求最小起飞次数。
from collections import deque, defaultdict
def solution(airports):
n = len(airports)
company_map = defaultdict(list)
for i, company in enumerate(airports):
company_map[company].append(i)
# BFS 初始化
queue = deque([(0, 0)])
visited = set()
visited.add(0)
while queue:
index, flights = queue.popleft()
# 如果到达终点
if index == n - 1:
return flights
# 访问相邻机场
for neighbor in (index - 1, index + 1):
if 0 <= neighbor < n and neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, flights + 1))
# 访问相同航空公司机场
for same_company_index in company_map[airports[index]]:
if same_company_index not in visited:
visited.add(same_company_index)
queue.append((same_company_index, flights + 1))
# 清空该航空公司,防止后续重复访问
company_map[airports[index]].clear()
if __name__ == "__main__":
# 测试用例
print(solution([10, 12, 13, 12, 14]) == 3) # 输出: True
print(solution([10, 11, 12, 13, 14]) == 4) # 输出: True
print(solution([7, 7, 7, 8, 9, 7]) == 1) # 输出: True
试题5:病毒在封闭空间中的传播时间
问题描述:
在一个封闭的房间中,排列着 n 行 m 列的座位,每个座位间距为 1 米。房间中每个座位上都坐着一人,部分人戴了口罩,部分人未戴口罩。已知房间中有一位已经感染病毒的人,病毒可以每秒向相邻座位传播 1 米。对于戴口罩的人,病毒需要两秒才能成功感染,或者需要在一秒内从两个相邻的感染者处同时被感染。设计一个算法,计算病毒感染房间内所有人所需的最短时间。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
int stepx[4] = {0, 1, 0, -1};
int stepy[4] = {1, 0, -1, 0};
int check(int x, int y, int row, int column) {
if (x < 0 || x >= row || y < 0 || y >= column) {
return 0;
}
return 1;
}
int solution(int row_n, int column_m, std::vector<std::vector<int>> seats,
std::vector<int> patient) {
// Please write your code here
int now1[101][101] = {{0}};
int now2[101][101] = {{0}};
if (!check(patient[0], patient[1], row_n, column_m)) {
return 0;
}
if (row_n == 1 && column_m == 1) {
return 0;
}
now1[patient[0]][patient[1]] = 2;
now2[patient[0]][patient[1]] = 2;
int i = 0, j = 0, sum = 0, k = 0, tx = 0, ty = 0;
while (true) {
sum++;
for (i = 0; i < row_n; i++) {
for (j = 0; j < column_m; j++) {
if (now1[i][j] >= 2) {
for (k = 0; k < 4; k++) {
tx = i + stepx[k];
ty = j + stepy[k];
if (check(tx, ty, row_n, column_m)) {
if (seats[tx][ty] == 0) {
now2[tx][ty] = 2;
} else if (seats[tx][ty] == 1) {
now2[tx][ty]++;
}
}
}
}
}
}
int a = 0;
for (i = 0; i < row_n; i++) {
for (j = 0; j < column_m; j++) {
// cout << now1[i][j] << " ";
now1[i][j] = now2[i][j];
if (now2[i][j] < 2) {
a = 1;
}
}
// cout << "\n";
}
// cout << "\n";
if (!a) {
// cout << sum << "\n";
return sum;
}
}
}
int main() {
// You can add more test cases here
std::vector<std::vector<int>> testSeats1 = {
{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 1, 1}, {0, 0, 0, 1}};
std::vector<std::vector<int>> testSeats2 = {
{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 1, 1}, {0, 0, 0, 1}};
std::vector<std::vector<int>> testSeats3 = {
{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
std::vector<std::vector<int>> testSeats4 = {
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
std::vector<std::vector<int>> testSeats5 = {{1}};
std::cout << (solution(4, 4, testSeats1, {2, 2}) == 6) << std::endl;
std::cout << (solution(4, 4, testSeats2, {2, 5}) == 0) << std::endl;
std::cout << (solution(4, 4, testSeats3, {2, 2}) == 4) << std::endl;
std::cout << (solution(4, 4, testSeats4, {2, 2}) == 6) << std::endl;
std::cout << (solution(1, 1, testSeats5, {0, 0}) == 0) << std::endl;
return 0;
}
试题6:视频推荐的算法
问题描述:
西瓜视频正在开发一个新功能,旨在将访问量达到80百分位数以上的视频展示在首页的推荐列表中。实现一个程序,计算给定数据中的80百分位数。
例如:假设有一个包含从1到100的整数数组,80百分位数的值为80,因为按升序排列后,第80%位置的数字就是80。
99 百分位数:假如有 N 个数据,将数据从小到大排列,99 百分位数是第 N99%位置处的数据(遇到小数时四舍五入获取整数)。一般计算逻辑是先排序,定位到 N99%的位置。返回该位置处的数据。同理,80 百分位数就是第 N*80%位置处的数据。
#include <iostream>
#include <string>
#include <vector>
#include<sstream>
#include <algorithm>
int get80Percentile(const std::vector<int>& visits) {
if (visits.empty()) {
return 0;
}
// 复制访问量数组并排序
std::vector<int> sortedVisits = visits;
std::sort(sortedVisits.begin(), sortedVisits.end());
// 计算 80 百分位数的位置
int N = sortedVisits.size();
int position = static_cast<int>(N * 0.8 + 0.5);
if (position == 0) {
position = 1;
}
if (position > N) {
position = N;
}
return sortedVisits[position - 1];
}
int solution(std::string data) {
// Please write your code here
std::vector<int> intArray;
std::stringstream ss(data);
std::string temp;
// 使用getline读取字符串
while (std::getline(ss, temp, ',')) {
intArray.push_back(std::stoi(temp));
}
return get80Percentile(intArray);
return -2;
}
int main() {
std::cout << (solution("10,1,9,2,8,3,7,4,6,5") == 8) << std::endl;
std::cout << (solution("1,0,8,7,3,9,12,6,4,15,17,2,14,5,10,11,19,13,16,18") == 15) << std::endl;
std::cout << (solution("76,100,5,99,16,45,18,3,81,65,102,98,36,4,2,7,22,66,112,97,68,82,37,90,61,73,107,104,79,14,52,83,27,35,93,21,118,120,33,6,19,85,49,44,69,53,67,110,47,91,17,55,80,78,119,15,11,70,103,32,9,40,114,26,25,87,74,1,30,54,38,50,8,34,28,20,24,105,106,31,92,59,116,42,111,57,95,115,96,108,10,89,23,62,29,109,56,58,63,41,77,84,64,75,72,117,101,60,48,94,46,39,43,88,12,113,13,51,86,71") == 96) << std::endl;
return 0;
}