青训营-豆包MarsCode技术训练营试题解析三

介绍

‌豆包青训营‌是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目,主要面向在校大学生。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用‌。

课程内容和方向

豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率‌。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习‌,

本文提供训练营试题解析供参考

试题1:小E的射击训练

问题描述:
小E正在训练场进行射击练习,靶有10个环,靶心位于坐标(0, 0)。每个环对应不同的得分,靶心内(半径为1)得10分,依次向外的每个环分数减少1分。若射击点在某个半径为i的圆内,则得11-i分。如果射击点超出所有的环,则得0分。

根据给定的射击坐标(x, y),请计算小E的射击得分。

import math

def solution(x: int, y: int) -> int:
    # 计算射击点 (x, y) 到靶心 (0, 0) 的距离
    distance = math.sqrt(x**2 + y**2)
    
    # 根据距离确定得分
    if distance <= 1:
        return 10
    elif distance <= 2:
        return 9
    elif distance <= 3:
        return 8
    elif distance <= 4:
        return 7
    elif distance <= 5:
        return 6
    elif distance <= 6:
        return 5
    elif distance <= 7:
        return 4
    elif distance <= 8:
        return 3
    elif distance <= 9:
        return 2
    elif distance <= 10:
        return 1
    else:
        return 0

if __name__ == '__main__':
    print(solution(1, 0) == 10)
    print(solution(1, 1) == 9)
    print(solution(0, 5) == 6)
    print(solution(3, 4) == 6)

试题2:完美偶数计数

问题描述:
小C定义了一个“完美偶数”。一个正整数 x 被认为是完美偶数需要满足以下两个条件:
1.x 是偶数;
2.x 的值在区间 [l,r]之间
现在,小C有一个长度为 n 的数组 a,她想知道在这个数组中有多少个完美偶数。

def solution(n: int, l: int, r: int, a: list) -> int:
    count = 0  # 用于统计完美偶数的数量
    
    for num in a:
        # 检查 num 是否是偶数
        if num % 2 == 0:
            # 检查 num 是否在区间 [l, r] 之间
            if l <= num <= r:
                count += 1  # 如果是完美偶数,计数加1
    
    return count

if __name__ == '__main__':
    print(solution(5, 3, 8, [1, 2, 6, 8, 7]) == 2)
    print(solution(4, 10, 20, [12, 15, 18, 9]) == 2)
    print(solution(3, 1, 10, [2, 4, 6]) == 3)

试题3:a替换函数

问题描述:
给定一个字符串s,编写一个函数,将字符串中的小写字母a替换为"%100",并返回替换后的字符串。

例如,对于字符串"abcdwa",所有a字符会被替换为"%100",最终结果为%100bcdw%100"。

def solution(s: str) -> str:
    # 初始化一个空列表来存储替换后的字符
    result = []
    
    # 遍历字符串中的每个字符
    for char in s:
        # 如果字符是 'a',则替换为 "%100"
        if char == 'a':
            result.append("%100")
        else:
            # 否则,保留原字符
            result.append(char)
    
    # 将列表转换为字符串并返回
    return ''.join(result)

if __name__ == '__main__':
    print(solution(s="abcdwa") == '%100bcdw%100')
    print(solution(s="banana") == 'b%100n%100n%100')
    print(solution(s="apple") == '%100pple')

试题4:红包运气排行榜

问题描述:
小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:抢到的金额越多,排名越靠前;如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小C和小U抢到的金额相同,但小C比小U先抢,则小C排在小U前面。

#include <bits/stdc++.h>
using namespace std;
 
// 自定义比较函数
bool cmp(const pair<string, int>& a, const pair<string, int>& b) {
    if (a.second != b.second) {
        return a.second > b.second; // 按照值从大到小排序
    }
    return false; // 如果值相同,保持插入顺序
}
 
vector<string> solution(int n, vector<string> s, vector<int> x) {
    // 使用 vector 来存储数据,并在插入时进行累加
    vector<pair<string, int>> vec;
    for (int i = 0; i < n; ++i) {
        bool found = false;
        for (auto& p : vec) {
            if (p.first == s[i]) {
                p.second += x[i];
                found = true;
                break;
            }
        }
        if (!found) {
            vec.push_back({s[i], x[i]});
        }
    }
    sort(vec.begin(), vec.end(), cmp);
    // 提取排序后的名字
    vector<string> result;
    for (const auto& p : vec) {
        result.push_back(p.first);
    }
    return result;
}
 
int main() {
    cout << (solution(4, {"a", "b", "c", "d"}, {1, 2, 2, 1}) == vector<string>{"b", "c", "a", "d"}) << endl;
    cout << (solution(3, {"x", "y", "z"}, {100, 200, 200}) == vector<string>{"y", "z", "x"}) << endl;
    cout << (solution(5, {"m", "n", "o", "p", "q"}, {50, 50, 30, 30, 20}) == vector<string>{"m", "n", "o", "p", "q"}) << endl;
    return 0;
}

试题5:Base32编码和解码问题

问题描述:
你需要实现一个 Base32 的编码和解码函数。

相比于 Base32,你可能更熟悉 Base64,Base64 是非常常见的用字符串形式表示二进制数据的方式,在邮件附件、Web 中的图片中都有广泛的应用。

Base32 是 Base64 的变种,与 Base64 不同的地方在于 Base64 以 6 bit 为一组作为索引,而 Base32 以 5 bit 为一组作为索引,每一组用一个 ASCII 字符表示。Base 64 总共需要 64 个字符表示,而 Base32 则只需要 32 个字符表示。

Base32 的编码流程如下:

对二进制数据进行预处理:如果二进制数据的 bit 数目不是 5 的倍数的话,在末尾补 0 直至为 5 的倍数。
以 5 bit 为一组进行分组。
将每一组的 5 bit 二进制转换为索引(0 - 31)。
在索引 - 字符转换表中查询索引对应的字符。
根据原始二进制数据的 bit 数目除以 40 后的余数,确定末尾需要补 + 的数目。
如果原始二进制数据 bit 数目除以 40 后的余数是 0 的话,不需要补 +。
如果余数是 8,补 6 个 +。
如果余数是 16,补 4 个 +。
如果余数是 24,补 3 个 +。
如果余数是 32,补 1 个 +。
Base32 的索引 - 字符转换表如下:

索引:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

字符:9 8 7 6 5 4 3 2 1 0 m n b v c x z a s d f g h j k l p o i u y t

你需要对字符串rawStr进行编码,并对encodedStr进行解码。

def base32_encode(rawStr):
    base32_chars = "9876543210mnbvcxzasdfghjklpoiuyt"
    binary_string = ''.join(format(ord(char), '08b') for char in rawStr)
    
   
    padding_length = (5 - len(binary_string) % 5) % 5
    binary_string += '0' * padding_length
    
    
    base32_indices = [int(binary_string[i:i+5], 2) for i in range(0, len(binary_string), 5)]
    
    
    encoded_str = ''.join(base32_chars[index] for index in base32_indices)
    
    
    original_length = len(rawStr) * 8
    remainder = original_length % 40
    if remainder == 8:
        encoded_str += '++++++'
    elif remainder == 16:
        encoded_str += '++++'
    elif remainder == 24:
        encoded_str += '+++'
    elif remainder == 32:
        encoded_str += '+'
    
    return encoded_str

def base32_decode(encodedStr):
    base32_chars = "9876543210mnbvcxzasdfghjklpoiuyt"
    
    # Split the input string by '+'
    parts = encodedStr.split('+')
    
    decoded_result = ''
    
    for part in parts:
        # Convert base32 characters to binary string
        base32_indices = [base32_chars.index(char) for char in part]
        binary_string = ''.join(format(index, '05b') for index in base32_indices)
        
        
        padding_count = (8 - len(part) % 8) % 8
        if padding_count == 6:
            bits_to_remove = 2
        elif padding_count == 4:
            bits_to_remove = 4
        elif padding_count == 3:
            bits_to_remove = 1
        elif padding_count == 1:
            bits_to_remove = 3
        else:
            bits_to_remove = 0
        
        
        if bits_to_remove > 0:
            binary_string = binary_string[:-bits_to_remove]
        
        
        decoded_chars = [chr(int(binary_string[i:i+8], 2)) for i in range(0, len(binary_string), 8)]
        
        decoded_result += ''.join(decoded_chars)
    
    return decoded_result

def solution(rawStr, encodedStr):
    encoded_result = base32_encode(rawStr)
    decoded_result = base32_decode(encodedStr)
    print(f"{encoded_result}:{decoded_result}")
    return f"{encoded_result}:{decoded_result}"



if __name__ == "__main__":
    #  You can add more test cases here
    print(solution("foo", "b0zj5+++") == "bljhy+++:bar" )
    print(solution("The encoding process represents 40-bit groups of input bits as output strings of 8 encoded characters.  Proceeding from left to right, a 40-bit input group is formed by concatenating 5 8bit input groups. These 40 bits are then treated as 8 concatenated 5-bit groups, each of which is translated into a single character in the base 32 alphabet.  When a bit stream is encoded via the base 32 encoding, the bit stream must be presumed to be ordered with the most-significant- bit first. That is, the first bit in the stream will be the high- order bit in the first 8bit byte, the eighth bit will be the low- order bit in the first 8bit byte, and so on.", "bljhy+++b0zj5+++") == "maf3m164vlahyl60vlds9i6svuahmiod58l3mi6sbglhmodfcbz61b8vb0fj1162c0jjmi6d58jhb160vlk2mu89b0fj1il9b4ls9oogcak2mu89cvp25pncbuls9oo359i79lncbvjh1ln558ahzknsb4aj1lnscbj7917zc0jh3ln4bafhill9bll3yo09vashbu89cajs9id0buf21n89b5z61b8vb0fj1160vlk2mu89bul3yunz58fj3163vul3pln558a2s166vuj33knfbgj37u60vlds9v0928a3su89v4j29unf58dj5oogc8lsi17fv8sj3l093zk79kd0cals9knsbfz21p64vkz21id4b4p3ml89b4ls9c89bvjhiko8cashiknfbgs79v0vb0fj1162c0jjmi6d4zz3mkn6v9z3yla9cuf3sko158fj316fc0zhiiobb4p3ml89v4j21ol9b5z23pncbuh3m166v8zj5kn6casj5160vkz21p6458a37io459ld5168vak3zkn7bgp7i189muf3moa9b5z35pnf58lj1id4b4hs9pnd58shikoxbash116hv4zs9u61bfz35kndbfz63ba9bgj33oo5v4j3cn89caf3m167v4p79iofc0sh7o09vgpj3u89b0ss9i6sbgljmon4bzz21ol9b0ss9oosbasj5ln558ohsu6158p3zl09vgjj3u8vcvfhcod0blfh3kncczhs9kd0czz3bpnscvp7i17fv8zj1160cbh79u61bfz3bpnscvp79kd0czz3soa9caf3m16dcal3mknv58ohso6b58a3m16fv8ss9p60buf7p16xc0s3mia9b0fj1160vkz21p6458d3siddczz6zkd0czz35ynfbfh79u61bfz3mpn2v8p3z167v4p79uo0vah79kd458p3zl09vajjcn09vul31lns58a3su89v4j79u61bfz3bpnscvp79c67v4p79kdlcassk168vls79iox58jhinz+:foobar" )

试题6:打点计数器的区间合并

问题描述:
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。

例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。

def solution(inputArray):
    # 1. 首先对区间进行排序,排序的依据是区间的起始值
    inputArray.sort(key=lambda x: x[0])
    
    # 2. 初始化一个列表来存储合并后的区间
    merged_intervals = []
    
    # 3. 遍历每个区间,进行合并
    for interval in inputArray:
        # 如果merged_intervals为空,或者当前区间的起始值大于merged_intervals最后一个区间的结束值
        if not merged_intervals or interval[0] > merged_intervals[-1][1]:
            # 直接将当前区间加入merged_intervals
            merged_intervals.append(interval)
        else:
            # 否则,合并当前区间到merged_intervals的最后一个区间
            merged_intervals[-1][1] = max(merged_intervals[-1][1], interval[1])
    
    # 4. 计算合并后的区间中唯一数字的数量
    count = 0
    for interval in merged_intervals:
        count += interval[1] - interval[0] + 1
    
    return count

if __name__ == "__main__":
    # 你可以添加更多测试用例
    testArray1 = [[1, 4], [7, 10], [3, 5]]
    testArray2 = [[1, 2], [6, 10], [11, 15]]

    print(solution(testArray1) == 9)
    print(solution(testArray2) == 12)

试题7:多米诺骨牌均衡状态

问题描述:
小S玩起了多米诺骨牌,他排列了一行骨牌,并可能将某些骨牌向左或向右推倒。随着骨牌连锁反应的进行,一些骨牌可能因为左右两侧受力平衡而保持竖立。现在小S想要知道在所有动作完成后,哪些骨牌保持竖立。

给定一个表示骨牌初始状态的字符串,其中:

“L” 表示该位置的骨牌将向左倒。
“R” 表示该位置的骨牌将向右倒。
“.” 表示该位置的骨牌初始时保持竖立。
模拟整个骨牌倒下的过程,求出最终仍然保持竖立的骨牌的数目和位置。

def solution(num, data):
    pre = ""
    while pre != data:
        pre = data
        data = data.replace("R.L", "X")
        data = data.replace("R.", "RR")
        data = data.replace(".L", "LL")
        data = data.replace("X", "R.L")
    num = 0
    upright_positions = []
    for i in range(len(data)):
        if data[i] == ".":
            num += 1
            upright_positions.append(i + 1)
    if num == 0:
        return "0"
    return f"{num}:{','.join(map(str, upright_positions))}"

试题8:叠盘子排序

问题描述:
小M有一个独特的方式来收拾家中的盘子。每次用餐后,他会将盘子按照他们的序号顺序叠放。盘子的序号都是唯一的整数,并且在收拾前就是递增的。小M的叠放规则是,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。需要编写程序帮助小M确定盘子的叠放方式。

例如,输入的盘子序号是 [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],按照小M的规则,连续递增序列 -3, -2, -1 可以叠在一起表示为 -3–1,而 18, 19, 20 可以叠在一起表示为 18-20。不满足连续递增至少3个的,如 2, 10, 15, 16 都应单独列出。

输入参数:
plates: 一个整数数组,表示盘子的序号
n: 盘子总数

def solution(plates, n):
    ans_string = ""
    i = 0
    while i < n:
        item = plates[i]
        ans_string += str(item)
        x = 1
        item_1 = item + 1
        item_2 = item + 2
        if item_1 in plates and item_2 in plates:
            x = 3
            while item + x in plates:
                x += 1
        if x > 1:
            ans_string += "-" + str(plates[i + x - 1])
            # print(i+x)
        ans_string += ","
        i += x
    ans_string = ans_string.strip(",")
    # print(ans_string)
    return ans_string
#
if __name__ == "__main__":
    print(solution([-3, -2, -1, 2, 10, 15, 16, 18, 19, 20], 10))

试题9:分组飞行棋棋子

问题描述:
小M和小F在玩飞行棋。游戏结束后,他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子,每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组,每组恰好5个,并且组内棋子的序号相同。小M希望知道是否可以按照这种方式对棋子进行分组。

例如,假设棋子序号为 [1, 2, 3, 4, 5],虽然只有5个棋子,但由于序号不同,因此不能形成有效的分组。如果序号是 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2],则可以形成两个有效分组,因此输出为 True。

def solution(nums):
    # 统计每个序号的棋子数量
    count_dict = {}
    for num in nums:
        if num in count_dict:
            count_dict[num] += 1
        else:
            count_dict[num] = 1
    
    # 检查每个序号的棋子数量是否能被5整除
    for count in count_dict.values():
        if count % 5 != 0:
            return "False"
    
    return "True"

if __name__ == "__main__":
    # 你可以添加更多的测试用例
    print(solution([1, 3, 4, 5, 6, 5, 4]) == "False")
    print(solution([1, 1, 1, 1, 2, 1, 2, 2, 2, 2]) == "True")
    print(solution([11, 45, 49, 37, 45, 38, 3, 47, 35, 49, 26, 16, 24, 4, 45, 39, 28, 26, 14, 22, 4, 49, 18, 4, 4, 26, 47, 14, 1, 21, 9, 26, 17, 12, 44, 28, 24, 24, 10, 31, 33, 32, 23, 41, 41, 19, 17, 24, 28, 46, 28, 4, 18, 23, 48, 45, 7, 21, 12, 40, 2, 19, 19, 28, 32, 6, 27, 43, 6, 18, 8, 27, 9, 6, 6, 31, 37, 15, 26, 20, 43, 3, 14, 40, 20]) == "False")

试题10:翻转增益的最大子数组和

问题描述:
小C面对一个由整数构成的数组,他考虑通过一次操作提升数组的潜力。这个操作允许他选择数组中的任一子数组并将其翻转,目的是在翻转后的数组中找到具有最大和的子数组。小C对这个可能性很感兴趣,并希望知道翻转后的数组中可能得到的最大子数组和是多少。

例如,数组是 1, 2, 3, -1, 4。小C可以选择翻转子数组 -1, 4 得到 1, 2, 3, 4, -1 或者翻转 1, 2, 3, -1 得到 -1, 3, 2, 1, 4,在这两种情况下,最大的子数组和都是 10。

备注:子数组 是数组中的一个连续部分。

输入
N: 数组的长度
data_array: 一个长度为 N 的整数数组
输出
请你返回执行翻转操作后(也可以选择不翻转),数组中可能获得的最大子数组和。

def solution(N, data_array):
    # 计算原始数组的最大子数组和
    def kadane(arr):
        max_ending_here = max_so_far = arr[0]
        for x in arr[1:]:
            max_ending_here = max(x, max_ending_here + x)
            max_so_far = max(max_so_far, max_ending_here)
        return max_so_far

    # 计算原始数组的最大子数组和
    max_sum_original = kadane(data_array)

    # 计算翻转后的最大子数组和
    max_sum_flipped = float('-inf')
    for i in range(N):
        for j in range(i, N):
            # 翻转子数组 data_array[i:j+1]
            flipped_array = data_array[:i] + data_array[i:j+1][::-1] + data_array[j+1:]
            # 计算翻转后的最大子数组和
            max_sum_flipped = max(max_sum_flipped, kadane(flipped_array))

    # 返回原始数组的最大子数组和与翻转后的最大子数组和中的最大值
    return max(max_sum_original, max_sum_flipped)

if __name__ == "__main__":
    # 你可以添加更多测试用例
    array1 = [-85, -11, 92, 6, 49, -76, 28, -16, 3, -29, 26, 37, 86, 3, 25, -43, -36, -27, 45, 87, 91, 58, -15, 91, 5, 99, 40, 68, 54, -95, 66, 49, 74, 9, 24, -84, 12, -23, -92, -47, 5, 91, -79, 94, 61, -54, -71, -36, 31, 97, 64, -14, -16, 48, -79, -70, 54, -94, 40, 37, 47, -58, 6, 62, 19, 8, 32, 65, -81, -27, 14, -18, -34, -64, -97, -21, -76, 51, 0, -79, -22, -78, -95, -90, 4, 82, -79, -85, -64, -79, 63, 49, 21, 97, 47, 16, 61, -46, 54, 44]
    print(solution(5, [1,2,3,-1,4]) == 10 )
    print(solution(100, array1) == 1348)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HappyAcmen

非常感谢大佬的鼓励!感谢感谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值