高木さんBlog高木さん

字节掘金青训营题解(持续更新,已更新至79题)

字节掘金青训营题解(持续更新,已更新至79题)

本人正在狂写赶工,不要着急,尽量会把所有题都写出来的,可能旧题目和新题目之间有差异,后续会持续更新,都给大家展示出来
题目链接

又改题目顺序了。。。。。。。。。。。。。。。。。烦躁,等有时间再重新编号吧#

今天看见更新C++判题了!!! 太好了#

当前已经 79

1.数字分组求偶数和#

Python代码#

Copy
def is_even(num): """Check if a number is even.""" return num % 2 == 0 def solution(numbers): # 记录偶数和奇数的个数 count_even = 1 # 可能选择的偶数数量 (初始化为 1) count_odd = 0 # 可能选择的奇数数量 (初始化为 0) for group in numbers: evens = sum(1 for char in str(group) if is_even(int(char))) odds = len(str(group)) - evens # 奇数数量 # 计算新的偶数和奇数组合数 new_count_even = count_even * evens + count_odd * odds new_count_odd = count_even * odds + count_odd * evens # 更新当前的偶数和奇数组合数 count_even = new_count_even count_odd = new_count_odd # 最终的结果是所有选择方案中,和为偶数的方案数量 return count_even if __name__ == "__main__": # You can add more test cases here print(solution([123, 456, 789]) == 14) print(solution([123456789]) == 4) print(solution([14329, 7568]) == 10)

2.徒步旅行中的补给问题#

Python代码#

Copy
def solution(n, k, data): dp = [[float('inf')] * (k + 1) for _ in range(n + 1)] dp[0][0] = 0 for i in range(1, n + 1): for l in range(k): for j in range(k): if l - j + 1 >= 0 and l - j + 1 <= k: dp[i][l] = min(dp[i][l], dp[i - 1][j] + (l - j + 1) * data[i - 1]) # print(dp) return dp[n][0] if __name__ == "__main__": print(solution(5, 2, [1, 2, 3, 3, 2]) == 9) print(solution(6, 3, [4, 1, 5, 2, 1, 3]) == 9) print(solution(4, 1, [3, 2, 4, 1]) == 10)

2.创意标题匹配问题#

Python 代码#

Copy
import re def solution(n, template, titles): # Please write your code here regex_pattern = '' i = 0 while i < len(template): if template[i] == '{': # 找到通配符开始 i += 1 while i < len(template) and template[i] != '}': i += 1 # 包含通配符,转换为 .* regex_pattern += '.*' else: regex_pattern += re.escape(template[i]) # 转义非通配符字符 i += 1 # 使用正则表达式进行匹配 regex = re.compile(f'^{regex_pattern}$') # 全匹配 results = [bool(regex.match(title)) for title in titles] # 将 results 列表转换为逗号分隔的字符串 results_str = ','.join(map(str, results)) return results_str if __name__ == "__main__": # You can add more test cases here testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"] testTitles2 = ["CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"] testTitles3 = ["abcdefg", "abefg", "efg"] print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1) == "True,False,False,True") print(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2) == "False,False,False,False,False,True") print(solution(3, "a{bdc}efg", testTitles3) == "True,True,False")

3.数字字符串格式化#

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; string solution(const string& s) { int idx = s.size(); for(int i = 0 ; i < s.size() ; i ++) if(s[i] == '.') { idx = i; break; } string str = ""; for(int i = s.size() - 1 ; i >= idx ; i --) str += s[i]; int cnt = 0; for(int i = idx - 1 ; i >= 0 ; i -- , cnt ++) { if(cnt % 3 == 0 && cnt) str += ","; str += s[i]; } reverse(str.begin() , str.end()); while(*str.begin() == ',' || *str.begin() == '0') str.erase(0 , 1); // cout << str << '\n'; return str; } int main() { cout << (solution("1294512.12412") == "1,294,512.12412") << endl; cout << (solution("0000123456789.99") == "123,456,789.99") << endl; cout << (solution("987654321") == "987,654,321") << endl; }

3.DNA序列编辑距离#

Python 代码#

Copy
def solution(dna1, dna2): m = len(dna1) n = len(dna2) # 创建一个(m+1) x (n+1)的二维列表来保存编辑距离 dp = [[0] * (n + 1) for _ in range(m + 1)] # 初始化第一行和第一列 for i in range(m + 1): dp[i][0] = i # 从dna1到空字符串的操作数为i(删除操作) for j in range(n + 1): dp[0][j] = j # 从空字符串到dna2的操作数为j(插入操作) # 填充DP表 for i in range(1, m + 1): for j in range(1, n + 1): if dna1[i - 1] == dna2[j - 1]: dp[i][j] = dp[i - 1][j - 1] # 字符匹配,无需操作 else: dp[i][j] = min(dp[i - 1][j] + 1, # 删除操作 dp[i][j - 1] + 1, # 插入操作 dp[i - 1][j - 1] + 1) # 替换操作 return dp[m][n] # 返回最终的编辑距离 if __name__ == "__main__": # You can add more test cases here print(solution("AGCTTAGC", "AGCTAGCT") == 2 ) print(solution("AGCCGAGC", "GCTAGCT") == 4)

4.二分数字组合 (原35.二分数字)#

问题描述(原问题题干)#

给定一个数组,请你把数组里的数字分为两组,使一组数字和的个位数等于 A(1 ≤ A ≤ 9),且剩余数字和的个位数等于 B(1 ≤ B ≤ 9);或者一组数字的个数为零,但剩余数字和的个位数等于 A 或 B。请问一共有多少种划分方式?

备注:

  1. 数组里的数字可以相等,但每个数字都是独一无二的。
    比如数组 a 等于[1, 1, 1],A 等于 1,B 等于 2,则一共有三组划分方式:
    第一种:
    A:a[0]
    B:a[1]、a[2]
    第二种:
    A:a[1]
    B:a[0]、a[2]
    第三种:
    A:a[2]
    B:a[0]、a[1]

  2. 可以将所有数字都划分到同一组,使其和的个位数等于 A 或 B;另一组为空
    比如数组 a 等于[1, 1, 1],A 等于 3,B 等于 5,则共有一组划分方式:
    A:a[0]、a[1]、a[2]
    B:空

输入格式#

输入第一行包含三个整数 n、A、B(1 ≤ n ≤ 100000,1 ≤ A ≤ 9,1 ≤ B ≤ 9),n 代表需要数组中的数字个数。

第二行,有 n 个元素,代表数组内的数字(1 ≤ 每个数字 ≤ 9)。

输出格式#

输出一共有多少种划分方式,结果对 10000007 取余。

输入样例

样例 1

3 1 2

1 1 1

样例 2

3 3 5

1 1 1

样例 3

2 1 1

1 1

输出样例

样例 1

3

样例 2

1

样例 3

2

题目解析#

线性dp

C++代码#

Copy
#include <iostream> #include <vector> #include <numeric> using namespace std; int solution(int n, int A, int B, vector<int>& array_a) { // 将元素规范化到 [0, 9] 的范围内 for (int& x : array_a) { x %= 10; } int total_sum = accumulate(array_a.begin(), array_a.end(), 0) % 10; // 检查总和是否符合要求 if (total_sum == A || total_sum == B) { return 1; } if (total_sum != (A + B) % 10) { return 0; } // 动态规划数组初始化 vector<vector<int>> f(n + 1, vector<int>(10, 0)); f[0][0] = 1; // 动态规划更新 for (int i = 1; i <= n; ++i) { for (int j = 0; j < 10; ++j) { f[i][j] += f[i - 1][j]; f[i][j] += f[i - 1][(j - array_a[i - 1] + 10) % 10]; } } return f[n][B]; } int main() { // You can add more test cases here std::vector<int> array1 = {1, 1, 1}; std::vector<int> array2 = {1, 1, 1}; std::vector<int> array3 = {1, 1}; std::cout << (solution(3, 1, 2, array1) == 3) << std::endl; std::cout << (solution(3, 3, 5, array2) == 1) << std::endl; std::cout << (solution(2, 1, 1, array3) == 2) << std::endl; return 0; }

Python代码#

Copy
def solution(n, A, B, array_a): array_a = [x % 10 for x in array_a] total_sum = sum(array_a) total_sum %= 10 if (total_sum == A or total_sum == B): return 1 if (total_sum != (A + B) % 10): return 0 f = [[0 for _ in range(10)] for _ in range(n + 1)] f[0][0] = 1 for i in range(1 , n + 1): for j in range(10): f[i][j] += f[i - 1][j] f[i][j] += f[i - 1][(j - array_a[i - 1] + 10) % 10] return f[n][B] if __name__ == "__main__": # You can add more test cases here print(solution(3, 1, 2, [1,1,1]) == 3 ) print(solution(3, 3, 5, [1,1,1]) == 1 ) print(solution(2, 1, 1, [1,1]) == 2 ) print(solution(13 , 8 , 3 , [21,9,16,7,9,19,8,4,1,17,1,10,16]) == 1)

5.寻找最大葫芦#

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; vector<int> solution(int n, int max, const vector<int>& array) { map<int , int> p; for(auto t : array) if(t == 1) p[14] ++; else p[t] ++; vector<int> a , b; for(auto [k , v] : p) if(v >= 3) a.push_back(k) , b.push_back(k); else if(v >= 2) b.push_back(k); sort(a.begin() , a.end() , greater<int>()); sort(b.begin() , b.end() , greater<int>()); for(auto ta : a) for(auto tb : b) if(ta != tb) { if(ta == 14) ta = 1; if(tb == 14) tb = 1; int sum = ta * 3 + tb * 2; if(sum <= max) return {ta , tb}; } return {0, 0}; } int main() { // Add your test cases here vector<int> result1 = solution(9, 34, {6, 6, 6, 8, 8, 8, 5, 5, 1}); cout << (result1 == vector<int>{8, 5}) << endl; vector<int> result2 = solution(9, 37, {9, 9, 9, 9, 6, 6, 6, 6, 13}); cout << (result2 == vector<int>{6, 9}) << endl; vector<int> result3 = solution(9, 40, {1, 11, 13, 12, 7, 8, 11, 5, 6}); cout << (result3 == vector<int>{0, 0}) << endl; return 0; }

5.计算从位置 x 到 y 的最少步数(原2.计算位置 x 到 y 的最少步数)#

原问题描述#

AB 实验同学每天都很苦恼如何可以更好地进行 AB 实验,每一步的流程很重要,我们目标为了缩短所需的步数。

我们假设每一步对应到每一个位置。从一个整数位置 x 走到另外一个整数位置 y,每一步的长度是正整数,每步的值等于上一步的值 -1+0+1。求 xy 最少走几步。并且第一步必须是 1,最后一步必须是 1,从 xy 最少需要多少步。

样例说明#

  • 整数位置 x12,另外一个整数位置 y6,我们需要从 x 走到 y,最小的步数为:1221,所以我们需要走 4 步。
  • 整数位置 x34,另外一个整数位置 y45,我们需要从 x 走到 y,最小的步数为:123221,所以我们需要走 6 步。
  • 整数位置 x50,另外一个整数位置 y30,我们需要从 x 走到 y,最小的步数为:12344321,所以我们需要走 8 步。

输入格式#

输入包含 2 个整数 xy。(0<=x<=y<2^31

输出格式#

对于每一组数据,输出一行,仅包含一个整数,从 xy 所需最小步数。

输入样例#

Copy
12 6 34 45 50 30

输出样例#

Copy
4 6 8

题目解析#

简单数学

C++代码#

Copy
#include <bits/stdc++.h> int solution(int xPosition, int yPosition) { int x = abs(xPosition - yPosition); int cnt = 1; while(x > 2 * cnt) { x -= 2 * cnt; cnt ++; } if(x == 0) return cnt * 2 - 2; if(x > 0 && x <= cnt) return cnt * 2 - 1; if(x >= cnt && x <= 2 * cnt) return cnt * 2; return 0; } int main() { // You can add more test cases here std::cout << (solution(12, 6) == 4) << std::endl; std::cout << (solution(34, 45) == 6) << std::endl; std::cout << (solution(50, 30) == 8) << std::endl; return 0; }

Python 代码#

Copy
def solution(xPosition, yPosition): x = abs(xPosition - yPosition) cnt = 1 while x > 2 * cnt: x -= 2 * cnt cnt += 1 if x == 0: return cnt * 2 - 2 if x > 0 and x <= cnt: return cnt * 2 - 1 if x >= cnt and x <= 2 * cnt: return cnt * 2 return 0 if __name__ == "__main__": # You can add more test cases here print(solution(12, 6) == 4 ) print(solution(34, 45) == 6) print(solution(50, 30) == 8)

6.环状 DNA 序列的最小表示法(原4.环状 DNA 序列整理)#

原问题描述#

环状 DNA 又称超螺旋,即一段碱基序列呈现环状,在分析时,需要将相同序列的环状 DNA 分到相同组内,现需将环状碱基序列按照最小表示法进行排序。

一段长度为 n 的碱基序列,按照顺时针方向,碱基序列可以从任意位置起开始该序列顺序,因此长度为 n 的碱基序列有 n 种表示法。例如:长度为 6 的碱基序列 CGAGTC,有 CGAGTCGAGTCCAGTCCG 等表示法。在这些表示法中,字典序最小的称为“最小表示”。

输入一个长度为 nn <= 100)的环状碱基序列(只包含 ACGT 这 4 种碱基)的一种表示法,输出该环状碱基序列的最小表示。

例如:
ATCA 的最小表示是 AATC
CGAGTC 的最小表示是 AGTCCG

输入描述#

一段 DNA 碱基序列

输出描述#

DNA 碱基序列的最小表示

备注
n <= 100
DNA 由大写英文字母 AGCT 组成

示例 1
输入:ATCA
输出:AATC

示例 2
输入:CGAGTC
输出:AGTCCG

题目解析#

语法题

C++代码#

Copy
#include <algorithm> #include <bits/stdc++.h> #include <string> #include <vector> using namespace std; string solution(string dna_sequence) { vector<string> ans; for(int i = 0 ; i < dna_sequence.size(); i ++) { string res = ""; for(int j = 0 ; j < dna_sequence.size(); j ++) res = res + dna_sequence[(i + j) % dna_sequence.size()]; ans.push_back(res); } sort(ans.begin() , ans.end()); return ans[0]; } int main() { // You can add more test cases here cout << (solution("ATCA") == "AATC") << endl; cout << (solution("CGAGTC") == "AGTCCG") << endl; cout << (solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG") == "AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG") << endl; return 0; }

Python 代码#

Copy
def solution(dna_sequence): ans = [] for i in range(len(dna_sequence)): res = "" for j in range(len(dna_sequence)): res += dna_sequence[(i + j) % len(dna_sequence)] # 轮转拼接 ans.append(res) ans.sort() # 对结果进行排序 return ans[0] # 返回字典序最小的轮转序列 if __name__ == "__main__": # You can add more test cases here print(solution("ATCA") == "AATC") print(solution("CGAGTC") == "AGTCCG") print(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG") == "AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG")

7.最小替换子串长度#

Python代码#

Copy
def solution(input): n = len(input) target = n // 4 # 目标频次 # 统计频次 freq = {'A': 0, 'S': 0, 'D': 0, 'F': 0} for c in input: freq[c] += 1 # 已经平衡 if all(f == target for f in freq.values()): return 0 # 尝试每个可能的长度 for length in range(1, n + 1): # 检查每个起始位置 for start in range(n - length + 1): # 计算替换该子串后的频次 temp = freq.copy() for i in range(start, start + length): temp[input[i]] -= 1 # 检查是否可以通过添加length个字符达到平衡 max_count = max(temp.values()) min_count = min(temp.values()) if max_count - min_count <= length: # 检查是否可以分配length个字符来达到平衡 needed = sum(max(0, target - count) for count in temp.values()) if needed <= length: return length return n if __name__ == "__main__": # 测试用例 print(solution("ADDF") == 1) # True print(solution("ASAFASAFADDD") == 3) # True print(solution("SSDDFFFFAAAS") == 1) # True print(solution("AAAASSSSDDDDFFFF") == 0) # True print(solution("AAAADDDDAAAASSSS") == 4) # True

9.大数和中的极值位距离#

Python代码#

Copy
def add_large_numbers(num1: str, num2: str) -> str: """实现大数加法""" # 将较短的数字在前面补0,使两个数字长度相同 max_len = max(len(num1), len(num2)) num1 = num1.zfill(max_len) num2 = num2.zfill(max_len) carry = 0 # 进位 result = [] # 从右向左逐位相加 for i in range(max_len - 1, -1, -1): digit_sum = int(num1[i]) + int(num2[i]) + carry carry = digit_sum // 10 result.append(str(digit_sum % 10)) # 处理最后的进位 if carry: result.append(str(carry)) # 反转结果并转换为字符串 return ''.join(result[::-1]) def find_min_distance(sum_str: str) -> int: """在结果字符串中找出最大值和最小值的最小位置差""" if len(set(sum_str)) == 1: # 如果所有数字都相同 return 0 # 找到最大和最小数字 max_digit = max(sum_str) min_digit = min(sum_str) # 记录每个数字最后出现的位置 last_pos = {} # 记录当前找到的最小距离 min_distance = len(sum_str) # 遍历字符串,记录位置并更新最小距离 for i, digit in enumerate(sum_str): if digit == max_digit or digit == min_digit: # 如果另一个极值已经出现过 for prev_digit, prev_pos in last_pos.items(): if (digit == max_digit and prev_digit == min_digit) or \ (digit == min_digit and prev_digit == max_digit): min_distance = min(min_distance, i - prev_pos) last_pos[digit] = i return min_distance - 1 if min_distance != len(sum_str) else min_distance def solution(string1: str, string2: str) -> int: """主函数:计算两个大数相加后的最大最小值位置差""" # 计算两数之和 sum_result = add_large_numbers(string1, string2) # 计算最大最小值的最小位置差 return find_min_distance(sum_result) if __name__ == "__main__": # 测试用例 print(solution("111", "222") == 0) # 结果是"333",所有数字相同,差距为0 print(solution("111", "34") == 1) # 结果是"145",最大值5和最小值1的位置差为1 print(solution("999", "1") == 0) # 结果是"1000",最大值1和最小值0的位置差为0 print(solution("525", "474") == 0) # 结果是"999",所有数字相同,差距为0 print(solution("5976762424003073", "6301027308640389") == 6) # 大数测试 # 额外测试用例 print(solution("99", "1") == 0) # 结果是"100",测试进位情况 print(solution("555", "444") == 0) # 结果是"999",测试全相同数字

9.超市里的货物架调整#

C++ 代码#

Copy
#include <bits/stdc++.h> using namespace std; int solution(int n, int m, string s, string c) { map<char , int> ps , pc; for(auto it : s) ps[it] ++; for(auto it : c) pc[it] ++; int cnt = 0; for(auto [k , v] : pc) cnt += min(ps[k] , v); return cnt; } int main() { cout << (solution(3, 4, "abc", "abcd") == 3) << endl; cout << (solution(4, 2, "abbc", "bb") == 2) << endl; cout << (solution(5, 4, "bcdea", "abcd") == 4) << endl; return 0; }

10.小F的永久代币卡回本计划#

C++代码#

Copy
\#include <iostream> using namespace std; int solution(int a, int b) { return (a / b) + (a % b != 0); } int main() { cout << (solution(10, 1) == 10) << endl; cout << (solution(10, 2) == 5) << endl; cout << (solution(10, 3) == 4) << endl; return 0; }

11.观光景点组合得分问题#

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; int solution(vector<int> values) { if(values.size() == 1) return 0; int maxv = 0 , res = 0; for(int i = 0 ; i < values.size() ; i ++) { res = max(res , values[i] - i + maxv); maxv = max(maxv , values[i] + i); } return res; // Placeholder return } int main() { cout << (solution({8, 3, 5, 5, 6}) == 11) << endl; cout << (solution({10, 4, 8, 7}) == 16) << endl; cout << (solution({1, 2, 3, 4, 5}) == 8) << endl; return 0; }

13.构造特定数组的逆序拼接#

Python代码#

Copy
def solution(n: int) -> list: result = [] for i in range(1, n + 1): # 生成从 n 到 i 的逆序列表 reverse_list = list(range(n, i - 1, -1)) # 将这个逆序列表追加到 result 中 result.extend(reverse_list) return result if __name__ == '__main__': print(solution(3) == [3, 2, 1, 3, 2, 3]) print(solution(4) == [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]) print(solution(5) == [5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5])

14.数组元素之和最小化#

C++代码#

Copy
#include <iostream> #include <vector> #include <string> using namespace std; int solution(int n, int k) { int sum = 0; for(int i = 1 ; i <= n ; i ++) sum += k * i; return sum; } int main() { std::cout << (solution(3, 1) == 6) << std::endl; std::cout << (solution(2, 2) == 6) << std::endl; std::cout << (solution(4, 3) == 30) << std::endl; }

50.优化青海湖至景点X的租车路线成本(原1.青海湖租车之旅)#

原问题描述#

油价飞升的今天,我们尽量减少花费。我们出门旅游,有时候租车去旅游也是一种不错的方式。这次我们这次旅游是从「青海湖」到「景点 X」,景点 X 可以是「敦煌」、「月牙泉」等,线路的路径是唯一的,假设我们每走 1 km 消耗 1 L 的油,车油箱容量 400L。比如:如果「景点 X」是敦煌,我们在青海湖租车前油箱是 200L 的,在「景点 X」(敦煌)还车的时候也是 200L 的,路上有很多加油站,加油站在青海湖和「景点 X」的连线上。

输入格式#

第 1 行表示「青海湖」到「景点 X」的距离,距离最远不超过 10000 km。
第 2 行表示接下来 N 行表示 N 个加油站(N 为正整数)。
接下来 N(1 <= N <= 100)行表示,每一个加油站情况。每一个加油站包括距离「景点 X」的距离 a km(0 <= a <= 10000),以及每升汽油的价格 b 元(0 <= b <= 2000),a 和 b 均为正整数。

输出格式#

如果不能到达目的地「景点 X」,输出 Impossible。
如果能到达目的地「景点 X」,输出最小花费多少元。

输入样例
500
4
100 1
200 30
400 40
300 20

输出样例
4300

题目解析#

线性dp

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; int dp[110][410]; // dp(i , j) 表示到第i个点油量剩余j的最小花费 string solution(int distance, int n, vector<vector<int>> gasStations) { gasStations.push_back({distance}); sort(gasStations.begin(), gasStations.end(), [&](vector<int> &a, vector<int> &b) { return a[0] < b[0]; }); vector<int> dis(n + 1); dis[0] = gasStations[0][0]; for (int i = 1; i <= n; i++) dis[i] = gasStations[i][0] - gasStations[i - 1][0]; memset(dp, 0x3f, sizeof dp); dp[0][200] = 0; for (int i = 1; i <= n; i++) { if (gasStations[i - 1][0] == distance) { n = i - 1; break; } for (int j = 0; j <= 400; j++) for (int k = 0; k <= 400; k++) if (j + dis[i - 1] - k >= 0 && gasStations[i - 1].size() > 1 && k >= dis[i - 1]) dp[i][j] = min(dp[i][j], dp[i - 1][k] + (j + dis[i - 1] - k) * gasStations[i - 1][1]); } // cout << "the answer is" << dp[n - 1][200 + dis[n - 1]] << '\n'; if (n < 1 || 200 + dis[n - 1] < 0 || dp[n][200 + dis[n - 1]] == 0x3f3f3f3f) return "Impossible"; return to_string(dp[n][200 + dis[n - 1]]); } int main() { vector<vector<int>> gasStations1 = { {100, 1}, {200, 30}, {400, 40}, {300, 20}}; vector<vector<int>> gasStations2 = {{100, 999}, {150, 888}, {200, 777}, {300, 999}, {400, 1009}, {450, 1019}, {500, 1399}}; vector<vector<int>> gasStations3 = {{101}, {100, 100}, {102, 1}}; vector<vector<int>> gasStations4 = { {34, 1}, {105, 9}, {9, 10}, {134, 66}, {215, 90}, {999, 1999}, {49, 0}, {10, 1999}, {200, 2}, {300, 500}, {12, 34}, {1, 23}, {46, 20}, {80, 12}, {1, 1999}, {90, 33}, {101, 23}, {34, 88}, {103, 0}, {1, 1}}; cout << (solution(500, 4, gasStations1) == "4300") << endl; cout << (solution(500, 7, gasStations2) == "410700") << endl; cout << (solution(500, 3, gasStations3) == "Impossible") << endl; cout << (solution(100, 20, gasStations4) == "0") << endl; cout << (solution(100, 0, vector<vector<int>>{}) == "Impossible") << endl; return 0; }

现在题目变化了,至少是200L就行,所以答案也要变

Python代码#

Copy
import sys def solution(distance, n, gasStations): maxCapacity = 400 inf = sys.maxsize # 按照加油站位置升序排序 gasStations.sort(key=lambda x: x[0]) # 计算每个加油站之间的距离 dis = [gasStations[0][0]] for i in range(1, len(gasStations)): dis.append(gasStations[i][0] - gasStations[i-1][0]) # 初始化 dp 数组 dp = [[inf] * (maxCapacity + 1) for _ in range(n + 2)] dp[0][200] = 0 # 初始状态,容量为200,花费为0 # 动态规划计算最小花费 for i in range(1, n + 1): for j in range(maxCapacity + 1): for k in range(maxCapacity + 1): if j + dis[i-1] - k >= 0 and k >= dis[i-1]: dp[i][j] = min(dp[i][j], dp[i-1][k] + (j + dis[i-1] - k) * gasStations[i-1][1]) # 判断是否可以到达终点 remaining_fuel = 200 + distance - gasStations[n-1][0] if remaining_fuel > maxCapacity or remaining_fuel < 0: return -1 result = inf for i in range(remaining_fuel, maxCapacity + 1): result = min(result, dp[n][i]) if result == inf: return -1 return result if __name__ == "__main__": # 测试样例 gas_stations1 = [[100, 1], [200, 30], [400, 40], [300, 20]] gas_stations2 = [[300, 25], [600, 35], [900, 5]] gas_stations3 = [[100, 50], [150, 45]] gas_stations4 = [[100, 10], [200, 20], [300, 30], [400, 40], [600, 15]] gas_stations5 = [[25, 100]] # 测试用例 print(solution(500, 4, gas_stations1) == 4300) print(solution(1000, 3, gas_stations2) == -1) print(solution(200, 2, gas_stations3) == 9000) print(solution(700, 5, gas_stations4) == 9500) print(solution(50, 1, gas_stations5) == 5000)

11.和的逆运算问题(原3.和的逆运算)#

原问题描述#

n 个整数两两相加可以得到 n(n - 1) / 2 个和。我们的目标是:根据这些和找出原来的 n 个整数。

输入格式#

输入每行一个整数 n2 < n < 10)开头,接下来是 n(n - 1) / 2 个整数,代表两两相加的和,相邻整数以空格隔开。

输出格式#

对于输入的每一行,输出一行,包含 n 个整数,按非降序排序,如果有多组解,任意输出一组即可。如果无解,输出 "Impossible"。

输入样例

  • 3 1269 1160 1663
  • 3 1 1 1
  • 5 226 223 225 224 227 229 228 226 225 227
  • 5 -1 0 -1 -2 1 0 -1 1 0 -1
  • 5 79950 79936 79942 79962 79954 79972 79960 79968 79924 79932

输出样例

  • 383 777 886
  • Impossible
  • 111 112 113 114 115
  • -1 -1 0 0 1
  • 39953 39971 39979 39983 39989

题目解析#

枚举第一个数的大小,直接暴力验证即可 时间复杂度O(n2m) n是数的个数 m是数的大小范围长度
这里3n10 所以不用特判,不用在意n2的时间问题

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; string solution(int n, vector<int> sums) { int sum = 0; for (auto s : sums) sum += s; if (sum % (n - 1) != 0) return "Impossible"; vector<int> ans(n); sort(sums.begin(), sums.end()); for (int i = -abs(sums[0]); i <= abs(sums[0]); i++) { ans[0] = i; map<int, int> p; for (auto s : sums) p[s]++; int idx = 1; for (auto [k, v] : p) { if (!v) continue; while (p[k]) { ans[idx] = k - ans[0]; int t; for (t = 0; t < idx; t++) if (p[ans[idx] + ans[t]]) p[ans[idx] + ans[t]]--; else break; if (t == idx) idx++; else break; } } if (idx == n) break; } string res = ""; for (int i = 0; i < n - 1; i++) res = res + to_string(ans[i]) + " "; return res + to_string(ans[n - 1]); } int main() { // You can add more test cases here vector<int> sums1 = {1269, 1160, 1663}; vector<int> sums2 = {1, 1, 1}; vector<int> sums3 = {226, 223, 225, 224, 227, 229, 228, 226, 225, 227}; vector<int> sums4 = {-1, 0, -1, -2, 1, 0, -1, 1, 0, -1}; vector<int> sums5 = {79950, 79936, 79942, 79962, 79954, 79972, 79960, 79968, 79924, 79932}; cout << (solution(3, sums1) == "383 777 886") << endl; cout << (solution(3, sums2) == "Impossible") << endl; cout << (solution(5, sums3) == "111 112 113 114 115") << endl; cout << (solution(5, sums4) == "-1 -1 0 0 1") << endl; cout << (solution(5, sums5) == "39953 39971 39979 39983 39989") << endl; return 0; }

Python 代码#

Copy
def solution(n, sums): total_sum = sum(sums) # Check if total_sum is divisible by (n-1) if total_sum % (n - 1) != 0: return "Impossible" ans = [0] * n sums.sort() # Iterate from -abs(sums[0]) to abs(sums[0]) for i in range(-abs(sums[0]), abs(sums[0]) + 1): ans[0] = i p = {s: sums.count(s) for s in sums} # Create a frequency map for sums idx = 1 for k in p.keys(): if p[k] == 0: continue while p[k] > 0: ans[idx] = k - ans[0] # Check how many previous indices can create the sum with ans[idx] t = 0 while t < idx: # If combination exists, decrement its count if p.get(ans[idx] + ans[t], 0): p[ans[idx] + ans[t]] -= 1 else: break t += 1 # If all previous pairs were valid if t == idx: idx += 1 else: break # If all n elements were successfully filled, break the loop if idx == n: break # Create the result string return " ".join(map(str, ans[:-1])) + " " + str(ans[-1]) if __name__ == "__main__": # You can add more test cases here print(solution(3, [1269, 1160, 1663]) == "383 777 886") print(solution(3, [1, 1, 1]) == "Impossible") print(solution(5, [226, 223, 225, 224, 227, 229, 228, 226, 225, 227]) == "111 112 113 114 115") print(solution(5, [-1, 0, -1, -2, 1, 0, -1, 1, 0, -1]) == "-1 -1 0 0 1") print(solution(5, [79950, 79936, 79942, 79962, 79954, 79972, 79960, 79968, 79924, 79932]) == "39953 39971 39979 39983 39989")

12.简单四则运算解析器(原5.简单四则运算)#

原问题描述#

实现一个基本的计算器来计算一个简单的字符串表达式的值。注意事项如下:

  • 输入是一个字符串表达式(可以假设所给定的表达式都是有效的)

  • 字符串表达式可以包含的运算符号为:左括号 (, 右括号 ), 加号 +, 减号 -

  • 可以包含的数字为:非负整数(< 10)

  • 字符串中不包含空格

  • 处理除法 case 的时候,可以直接省略小数部分结果,只保留整数部分参与后续运算

  • 请不要使用内置的库函数 eval

输入格式#

如:3+4*5/(3+2)

数据约束#

见题目描述

输出格式#

计算之后的数字

输入样例

  • 1+1
  • 3+4*5/(3+2)
  • 4+2*5-2/1
  • (1+(4+5+2)-3)+(6+8)

输出样例

  • 2
  • 7
  • 12
  • 23

题目分析#

表达式求值 栈

C++代码#

Copy
#include <bits/stdc++.h> #include <cctype> using namespace std; int solution(string expression) { stack<int> num; stack<char> op; map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}}; auto eval = [&] { int a = num.top(); num.pop(); int b = num.top(); num.pop(); char c = op.top(); op.pop(); int x; if (c == '+') x = a + b; else if (c == '-') x = b - a; else if (c == '*') x = a * b; else x = b / a; num.push(x); // cout << a << ' ' << c << ' ' << b << '=' << x << '\n'; }; for (int i = 0; i < expression.size(); i++) { char t = expression[i]; if (isdigit(t)) num.push(t - '0'); else if (t == '(') op.push(t); else if (t == ')') { while (op.top() != '(') eval(); op.pop(); } else { while (op.size() && op.top() != '(' && pr[op.top()] >= pr[t]) eval(); op.push(t); } } while (op.size()) eval(); return num.top(); } int main() { // You can add more test cases here cout << (solution("1+1") == 2) << endl; cout << (solution("3+4*5/(3+2)") == 7) << endl; cout << (solution("4+2*5-2/1") == 12) << endl; cout << (solution("(1+(4+5+2)-3)+(6+8)") == 23) << endl; return 0; }

Python代码#

Copy
def solution(expression): num = [] # 用来存放数字的栈 op = [] # 用来存放运算符的栈 pr = {'+': 1, '-': 1, '*': 2, '/': 2} # 运算符优先级 def eval(): a = num.pop() b = num.pop() c = op.pop() if c == '+': x = b + a elif c == '-': x = b - a elif c == '*': x = a * b else: # c == '/' x = b // a # 用整除,确保结果为整数 num.append(x) i = 0 while i < len(expression): t = expression[i] if t.isdigit(): # 判断是否为数字 num.append(int(t)) # 将字符转换为数字 elif t == '(': op.append(t) elif t == ')': while op and op[-1] != '(': eval() op.pop() # 弹出 '(' else: # 运算符 while op and op[-1] != '(' and pr[op[-1]] >= pr[t]: eval() op.append(t) i += 1 while op: # 处理剩余的运算符 eval() return num[-1] # 返回最终结果 if __name__ == "__main__": # You can add more test cases here print(solution("1+1") == 2) print(solution("3+4*5/(3+2)") == 7) print(solution("4+2*5-2/1") == 12) print(solution("(1+(4+5+2)-3)+(6+8)") == 23)

14.数字翻译成字符串的可能性#

Python代码#

Copy
def solution(num): # 转换为字符串,方便处理每一位 s = str(num) n = len(s) # dp[i]表示前i个数字的翻译方法数 dp = [0] * (n + 1) dp[0] = 1 # 空字符串有1种翻译方法 dp[1] = 1 # 第一个数字只有1种翻译方法 for i in range(2, n + 1): # 当前数字可以单独翻译 dp[i] = dp[i-1] # 检查当前数字能否与前一个数字组合翻译 two_digits = int(s[i-2:i]) # 组合的数字必须在10-25之间才能翻译 if 10 <= two_digits <= 25: dp[i] += dp[i-2] return dp[n] if __name__ == "__main__": print(solution(12258) == 5) # True print(solution(1400112) == 6) # True print(solution(2110101) == 10) # True print(solution(25) == 2) # True print(solution(1023) == 4) # True

15.二进制之和(原8.进制求和转换)#

原问题描述#

给定两个二进制字符串,返回他们的和(用十进制字符串表示)。输入为非空字符串且只包含数字 1 和 0 ,请考虑大数问题。时间复杂度不要超过 O(n^2),其中 n 是二进制的最大长度。

输入格式#

每个样例只有一行,两个二进制字符串以英文逗号“,”分割

输出格式#

输出十进制格式的两个二进制的和

输入样例

101,110

输出样例

11

数据范围

每个二进制不超过 100 个字符,JavaScript 语言下请考虑大数的情况。

题目解析#

高精度

C++代码(没做高精,因为样例小,懒得做)#

Copy
#include <bits/stdc++.h> using namespace std; string solution(string binary1, string binary2) { vector<int> s; int t = 0; for(int i = binary1.size() - 1 , j = binary2.size() - 1; i > -1 || j > -1 ; i -- , j --) { int a , b; if(i > -1) a = binary1[i] - '0'; else a = 0; if(j > -1) b = binary2[j] - '0'; else b = 0; if(a + b + t == 3) s.push_back(1) , t = 1; else if(a + b + t == 2) s.push_back(0) , t = 1; else if(a + b + t == 1) s.push_back(1) , t = 0; else s.push_back(0) , t = 0; } if(t) s.push_back(1); int ans = 0 , mi = 1; for(auto it : s) { ans += it * mi; mi *= 2; } return to_string(ans); } int main() { // You can add more test cases here cout << (solution("101", "110") == "11") << endl; cout << (solution("111111", "10100") == "83") << endl; cout << (solution("111010101001001011", "100010101001") == "242420") << endl; cout << (solution("111010101001011", "10010101001") == "31220") << endl; return 0; }

Python 自带高精度所以不用太管(话说这题数据量好像变小了?)

Python代码#

Copy
def solution(binary1, binary2): s = [] t = 0 # 反向遍历两个二进制字符串 i, j = len(binary1) - 1, len(binary2) - 1 while i >= 0 or j >= 0: a = int(binary1[i]) if i >= 0 else 0 b = int(binary2[j]) if j >= 0 else 0 total = a + b + t # 计算当前位的总和 if total == 3: s.append(1) t = 1 elif total == 2: s.append(0) t = 1 elif total == 1: s.append(1) t = 0 else: s.append(0) t = 0 i -= 1 j -= 1 if t > 0: s.append(1) # 如果有进位需要添加 # 计算结果的十进制值 ans = 0 for idx in range(len(s)): ans += s[idx] * (2 ** idx) # 计算每一位的值 return str(ans) if __name__ == "__main__": # You can add more test cases here print(solution("101", "110") == "11") print(solution("111111", "10100") == "83") print(solution("111010101001001011", "100010101001") == "242420") print(solution("111010101001011", "10010101001") == "31220")

16.贪心猫的鱼干大分配#

Python 代码#

Copy
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)

17.最大相等分割红包金额#

Python代码#

Copy
def solution(redpacks): n = len(redpacks) if n < 3: # 如果红包数量少于3个,无法分割 return 0 max_amount = 0 total = sum(redpacks) # 计算总和 # 计算前缀和,用于快速计算区间和 prefix_sum = [0] * (n + 1) for i in range(n): prefix_sum[i + 1] = prefix_sum[i] + redpacks[i] # 尝试所有可能的切分位置 # i 是第一刀的位置(切在i之后) # j 是第二刀的位置(切在j之后) for i in range(n-2): # 留出至少两个位置给中间和最后部分 for j in range(i, n-1): # j必须在i之后,且要留出至少一个位置给最后部分 first_part = prefix_sum[i+1] # 从开始到第一刀 third_part = prefix_sum[n] - prefix_sum[j+1] # 从第二刀到结束 # 如果第一部分等于第三部分,更新最大值 if first_part == third_part: max_amount = max(max_amount, first_part) # print(max_amount) return max_amount if __name__ == "__main__": # You can add more test cases here print(solution([1, 3, 4, 6, 7, 14]) == 14) print(solution([10000]) == 0) print(solution([52, 13, 61, 64, 42, 26, 4, 27, 25]) == 52) print(solution([10 , 10 , 10 , 10]) == 20) print(solution([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]) == 2627)

18.小U的最大连续移动次数问题#

C++ 代码#

Copy
#include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; int solution(int m, int n, vector<vector<int>>& a) { // 初始化visited数组 vector<vector<bool>> visited(m, vector<bool>(n, false)); // 定义DFS函数 function<int(int, int, bool)> dfs = [&](int x, int y, bool isUp) -> int { // 标记当前位置为已访问 visited[x][y] = true; int maxPath = 0; // 尝试向四个方向移动 vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; for (auto& dir : directions) { int nx = x + dir.first; int ny = y + dir.second; // 检查边界和是否已访问 if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny]) { // 检查是否满足上坡或下坡条件 if ((isUp && a[nx][ny] < a[x][y]) || (!isUp && a[nx][ny] > a[x][y])) { // 递归调用DFS maxPath = max(maxPath, dfs(nx, ny, !isUp)); } } } // 回溯:标记当前位置为未访问 visited[x][y] = false; // 返回当前路径长度 return maxPath + 1; }; int maxSteps = 0; // 遍历地图中的每个位置,尝试从该位置开始DFS for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { maxSteps = max(maxSteps, dfs(i, j, true)); maxSteps = max(maxSteps, dfs(i, j, false)); } } return maxSteps - 1; } int main() { vector<vector<int>> a1 = {{1, 2}, {4, 3}}; cout << (solution(2, 2, a1) == 3) << endl; vector<vector<int>> a2 = {{10, 1, 6}, {5, 9, 3}, {7, 2, 4}}; cout << (solution(3, 3, a2) == 8) << endl; vector<vector<int>> a3 = {{8, 3, 2, 1}, {4, 7, 6, 5}, {12, 11, 10, 9}, {16, 15, 14, 13}}; cout << (solution(4, 4, a3) == 11) << endl; }

20.RGB色值转换为整数值#

Python代码#

Copy
def solution(rgb): rgb_values = rgb[4:-1].split(',') # Convert the string values to integers r, g, b = [int(v.strip()) for v in rgb_values] # Convert to the integer value by shifting bits return (r << 16) + (g << 8) + b if __name__ == "__main__": # You can add more test cases here print(solution("rgb(192, 192, 192)") == 12632256 ) print(solution("rgb(100, 0, 252)") == 6553852) print(solution("rgb(33, 44, 55)") == 2174007)

23.阿D的最佳飞行路线探索#

Python代码#

Copy
from collections import defaultdict, deque def solution(airports): n = len(airports) if n <= 1: return 0 # 构建航空公司连接图 # 将相同航空公司的机场连接起来 company_airports = defaultdict(list) for i, airport in enumerate(airports): company_airports[airport].append(i) # BFS搜索最短路径 queue = deque([(0, 0)]) # (当前机场索引, 已飞行次数) visited = {0} # 记录已访问的机场 while queue: curr_airport, flights = queue.popleft() # 如果到达终点,返回飞行次数 if curr_airport == n - 1: return flights # 尝试所有可能的下一个机场 next_airports = set() # 1. 相邻机场 if curr_airport > 0: next_airports.add(curr_airport - 1) if curr_airport < n - 1: next_airports.add(curr_airport + 1) # 2. 相同航空公司的机场 curr_company = airports[curr_airport] next_airports.update(company_airports[curr_company]) # 遍历所有可能的下一个机场 for next_airport in next_airports: if next_airport not in visited: visited.add(next_airport) queue.append((next_airport, flights + 1)) return -1 # 如果无法到达终点 if __name__ == "__main__": # You can add more test cases here print(solution([10,12,13,12,14]) == 3 ) print(solution([10,11,12,13,14]) == 4 )

25.视频推荐的算法#

Python代码#

Copy
def solution(data): nums = list(map(int, data.split(','))) nums.sort() return nums[round(len(nums) * 0.8 - 1)] if __name__ == "__main__": # You can add more test cases here print(solution("10,1,9,2,8,3,7,4,6,5") == 8 ) print(solution("1,0,8,7,3,9,12,6,4,15,17,2,14,5,10,11,19,13,16,18") == 15) print(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)

26.魔法甜点之和:小包的新挑战(原23.不再贪心的小包)#

原问题描述#

众所周知,小包是一名非常喜欢吃甜点的小朋友,他在工作时特别爱吃下午茶里的甜食。

这天,下午茶小哥像往常一样送来了今天的 N 个甜点。小包对每个甜点有自己的喜爱值。但是今天的他不再贪心,并不想要喜爱值越高越好。他今天吃的甜点的喜爱值的和,一定要等于他的预期值 S。

但是他的预期值很高,小哥的甜点似乎不一定满足得了他,所以他准备了 M 个魔法棒,每个魔法棒可以对一个他要吃的甜点使用 1 次,使用后这个甜点的喜爱值会变成原来的喜爱值的阶乘。无法对一个甜点使用多次魔法棒,也不需要使用完所有魔法棒,也无法对不吃的甜点使用魔法棒。

小包很好奇,他有多少种方案,可以吃到喜爱值刚好为他的预期值的甜点。如果 2 种方案,食用了不同的甜点,或者对不同的甜点使用了魔法棒,都算作不同的方案。

输入格式#

输入第一行,包含 3 个整数 N,M,S

分别代表甜点的数量,魔法棒的数量,以及小包的预期值

接下来一行,包含 N 个整数,代表每个甜点的喜爱值

输出格式#

输出为一个整数,代表小包的方案数

输入样例 1

3 2 6

1 2 3

输出样例 1

5

输入样例 2

3 1 1

1 1 1

输出样例 2

6

注解

样例 1 中

小包有以下几种方案

选 1 2 3 不用魔法棒

选 1 2 3 对 1 用魔法棒

选 1 2 3 对 2 用魔法棒

选 1 2 3 对 1 2 用魔法棒

选 3 对 3 用魔法棒

样例 2 中 小包选任意 1 个甜点都是 1 种方案,每种方案都可以使用魔法棒不影响结果。所以一共 6 种方案

数据范围

10%的数据保证 M=0,1<=N<=10

30%的数据保证 1<=N<=12

100%的数据保证 1<=N<=25,0<=M<=N,1<=S<=1016

题目解析#

背包问题,空间优化+离散化

C++ 代码#

Copy
#include <bits/stdc++.h> using namespace std; typedef long long ll; map<pair<int, ll>, int> f; ll magic[100]; void pre() { magic[0] = 1; for (int i = 1; i < 100; i++) magic[i] = 1ll * magic[i - 1] * i; } int solution(int n, int m, int s, std::vector<int> like) { pre(); f.clear(); f[{0, 0ll}] = 1; for (int i = 1; i <= n; i++){ auto g = f; for (auto [k, v] : g) { int a = k.first; ll b = k.second; // cout << a << ' ' << b << ' ' << v << '\n'; if (b + like[i - 1] <= s) f[{a, b + like[i - 1]}] += v; if (a + 1 <= m && b + magic[like[i - 1]] <= s) f[{a + 1, b + magic[like[i - 1]]}] += v; } // cout << "--------\n"; } int sum = 0; for (int i = 0; i <= m; i++) sum += f[{i, s}]; // cout << sum << '\n'; return sum; } int main() { // You can add more test cases here std::vector<int> like1 = {1, 2, 3}; std::vector<int> like2 = {1, 1, 1}; std::cout << (solution(3, 2, 6, like1) == 5) << std::endl; std::cout << (solution(3, 1, 1, like2) == 6) << std::endl; return 0; }

Python 代码#

Copy
from collections import defaultdict # 计算阶乘的魔法数组 magic = [1] * 100 def pre(): for i in range(1, 100): magic[i] = magic[i - 1] * i def solution(n, m, s, like): pre() f = defaultdict(int) # 使用defaultdict来初始化map f[(0, 0)] = 1 # 初始状态 for i in range(1, n + 1): g = f.copy() # 备份当前的状态 for (a, b), v in g.items(): if b + like[i - 1] <= s: # 加入"喜欢"的数量 f[(a, b + like[i - 1])] += v if a + 1 <= m and b + magic[like[i - 1]] <= s: # 加入"喜欢的阶乘" f[(a + 1, b + magic[like[i - 1]])] += v sum_ = 0 for i in range(m + 1): sum_ += f[(i, s)] # 累加满足条件的结果 return sum_ if __name__ == "__main__": # You can add more test cases here print(solution(3, 2, 6, [1,2,3]) == 5 ) print(solution(3, 1, 1, [1,1,1]) == 6 )

29.查找热点数据问题#

Python代码#

Copy
from collections import Counter def solution(nums, k): p = Counter(nums) # 获取前 k 个最常见的元素 most_common_elements = p.most_common(k) # 按升序排列这些元素 sorted_elements = sorted([num for num, count in most_common_elements]) return sorted_elements if __name__ == "__main__": # You can add more test cases here print(solution([1,1,1,2,2,3], 2)) # 输出: [1, 2] print(solution([1], 1)) # 输出: [1] print(solution([4,4,4,2,2,2,3,3,1], 2)) # 输出: [2, 4]

30.打点计数器的区间合并#

Python 代码#

Copy
def solution(inputArray): if not inputArray: return 0 # 先对区间进行排序 inputArray.sort() # 初始化第一个区间的边界 l, r = inputArray[0] ans = 0 for i in range(0, len(inputArray)): pl, pr = inputArray[i] if r < pl: # 当前区间与前一个区间不重叠 ans += r - l + 1 l, r = pl, pr else: # 当前区间与前一个区间重叠 r = max(r, pr) # 加上最后一个区间的点数 ans += r - l + 1 return ans if __name__ == "__main__": # You can add more test cases here testArray1 = [[1,4], [7, 10], [3, 5]] testArray2 = [[1,2], [6, 10], [11, 15]] testArray3 = [[6,18],[2,16],[12,16],[5,16],[8,10],[1,9],[7,21],[2,3],[7,21],[6,7],[1,24],[9,17],[1,4],[12,18],[2,17],[4,19],[9,22],[8,24],[13,21],[7,8],[19,22],[22,23],[6,14]] print(solution(testArray1) == 7 ) print(solution(testArray2) == 9 ) print(solution(testArray3) == 23 )

32.多米诺骨牌均衡状态#

Copy
def solution(num, data): state = [0 for i in range(num)] ans = [] cnt = -1 for i in range(num): if(data[i] == '.' and cnt >= 0): cnt += 1 state[i] += cnt elif(data[i] == 'R'): cnt = 0 else: cnt = -1 cnt = -1 for i in range(num - 1 , -1 , -1): if(data[i] == '.' and cnt >= 0): cnt += 1 state[i] -= cnt elif(data[i] == 'L'): cnt = 0 else: cnt = -1 res = 0 for i in range(num): if(state[i] == 0 and data[i] == '.'): res += 1 ans.append(i + 1) str_ans = str(res) + ":" if(res > 0): for it in ans: str_ans = str_ans+ str(it) + "," return str_ans[0:len(str_ans) - 1] if __name__ == "__main__": # You can add more test cases here print(solution(14, ".L.R...LR..L..") == "4:3,6,13,14" ) print(solution(5, "R....") == "0" ) print(solution(1, ".") == "1:1" )

34.叠盘子排序#

Python 代码#

Copy
def solution(plates, n): plate_nums = list(map(int, plates)) result = [] start = 0 while start < len(plate_nums): end = start # 寻找连续的数字 while end + 1 < len(plate_nums) and plate_nums[end + 1] == plate_nums[end] + 1: end += 1 # 如果有两个或更多的连续数字 if end - start >= 2: result.append(f"{plate_nums[start]}-{plate_nums[end]}") else: for i in range(start, end + 1): result.append(str(plate_nums[i])) start = end + 1 return ','.join(result) if __name__ == "__main__": # You can add more test cases here print(solution("-3 -2 -1 2 10 15 16 18 19 20") == "-3--1,2,10,15,16,18-20" ) print(solution("-6 -3 -2 -1 0 1 3 4 5 7 8 9 10 11 14 15 17 18 19 20") == "-6,-3-1,3-5,7-11,14,15,17-20") print(solution("1 2 7 8 9 10 11 19") == "1,2,7-11,19")

38.分组飞行棋棋子#

Python代码#

Copy
from typing import Counter def solution(nums): p = Counter() for k in nums: p[k] += 1 for k in p: if(p[k] % 5 != 0): return "False" return "True" if __name__ == "__main__": # You can add more test cases here 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)

41.古生物DNA序列血缘分析#

Python代码#

Copy
def solution(dna1, dna2): # 获取两个DNA序列的长度 m = len(dna1) n = len(dna2) # 创建动态规划表格 # dp[i][j] 表示将dna1的前i个字符转换为dna2的前j个字符所需的最小操作次数 dp = [[0] * (n + 1) for _ in range(m + 1)] # 初始化第一行和第一列 # 第一行:将空字符串转换为dna2的前j个字符需要j次添加操作 for j in range(n + 1): dp[0][j] = j # 第一列:将dna1的前i个字符转换为空字符串需要i次删除操作 for i in range(m + 1): dp[i][0] = i # 填充动态规划表格 for i in range(1, m + 1): for j in range(1, n + 1): if dna1[i-1] == dna2[j-1]: # 如果当前字符相同,不需要额外操作 dp[i][j] = dp[i-1][j-1] else: # 取三种操作中的最小值: # 1. 替换操作:dp[i-1][j-1] + 1 # 2. 删除操作:dp[i-1][j] + 1 # 3. 添加操作:dp[i][j-1] + 1 dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 # 返回最终结果 return dp[m][n] if __name__ == "__main__": # You can add more test cases here print(solution("AGT", "AGCT") == 1) print(solution("", "ACGT") == 4) print(solution("GCTAGCAT", "ACGT") == 5)

44.数字魔法的加一操作#

Python代码#

Copy
from collections import deque MOD = 1000000007 def solution(n, k, numStr): numString = deque(int(numStr[i]) for i in range(n)) for t in range(k): l = len(numString) for i in range(l): num = numString.popleft() num += 1 if num == 10: numString.append(1) numString.append(0) else: numString.append(num) result = 0 l = len(numString) for i in range(l): result = (result * 10 + numString.popleft()) % MOD return result if __name__ == "__main__": # You can add more test cases here print(solution(3, 1, "798") == "8109") print(solution(3, 3, "798") == "103221")

48.连续子串和的整除问题#

Python代码#

Copy
def solution(n, b, sequence): mod_count = {0: 1} # 初始情况下,模值0出现1次(代表空子数组) current_prefix_sum = 0 result_count = 0 for num in sequence: # 更新前缀和 current_prefix_sum += num # 计算当前前缀和对b的模 mod_value = current_prefix_sum % b # 确保模值为正 if mod_value < 0: mod_value += b # 如果这个模值已经出现,累加结果 if mod_value in mod_count: result_count += mod_count[mod_value] # 更新模值出现的次数 mod_count[mod_value] = mod_count.get(mod_value, 0) + 1 return result_count if __name__ == "__main__": # You can add more test cases here sequence = [1, 2, 3] print(solution(3, 3, sequence) == 3)

51.找单独的数(原98.找单独的数)#

原问题描述#

有一堆数字,除了一个数字,其它的数字都是成对出现。班上的每个同学拿一个数字,正好将这些数字全部拿完,问如何快速找到拿了单独数字的同学?

输入格式#

  • 空格分隔输入所有的数字

输出格式#

  • 单独的那个数字

输入样例(1)#

Copy
1 1 2 2 3 3 4 5 5

输出样例(1)#

4

输入样例(2)#

Copy
0 1 0 1 2

输出样例(2)#

2

题目解析#

语法题

解法一#

C++代码#

Copy
#include <iostream> #include <vector> #include <map> int solution(std::vector<int> inp) { std::map<int , int> p; for(auto it : inp) p[it] ++; for(auto [k , v] : p) if(v == 1) return k; return -1; } int main() { // Add your test cases here std::cout << (solution({1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4) << std::endl; std::cout << (solution({0, 1, 0, 1, 2}) == 2) << std::endl; return 0; }

Python代码#

Copy
def solution(inp): p = {} for num in inp: if num in p: p[num] += 1 else: p[num] = 1 for k, v in p.items(): if v == 1: return k return -1 if __name__ == "__main__": # Add your test cases here print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4) print(solution([0, 1, 0, 1, 2]) == 2)

解法二#

C++代码#

Copy
#include <iostream> #include <vector> #include <map> int solution(std::vector<int> inp) { int x = 0; for(auto it : inp) x ^= it; return x; } int main() { // Add your test cases here std::cout << (solution({1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4) << std::endl; std::cout << (solution({0, 1, 0, 1, 2}) == 2) << std::endl; return 0; }

Python代码#

Copy
def solution(inp): x = 0 for i in inp: x ^= i # Edit your code here return x if __name__ == "__main__": # Add your test cases here print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4) print(solution([0, 1, 0, 1, 2]) == 2)

54.找出整型数组中占比超过一半的数#

Python代码#

Copy
from collections import Counter def solution(array): # 使用 Counter 统计每个元素的出现次数 count = Counter(array) # 遍历 Counter 对象,找到出现次数超过一半的元素 for num, freq in count.items(): if freq > len(array) // 2: return num return 0 # 如果没有找到符合条件的元素,返回 0 if __name__ == "__main__": # Add your test cases here print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)

55.最大矩形面积问题#

Python代码#

Copy
def solution(n, array): stack = [] max_area = 0 index = 0 while index < n: # If this bar is higher than the bar at stack top, push it to the stack if not stack or array[index] >= array[stack[-1]]: stack.append(index) index += 1 else: # Pop the top top_of_stack = stack.pop() # Calculate the area with array[top_of_stack] as the smallest (or minimum height) bar area = (array[top_of_stack] * ((index - stack[-1] - 1) if stack else index)) # Update max area, if needed max_area = max(max_area, area) # Now pop the remaining bars from stack and calculate area while stack: top_of_stack = stack.pop() area = (array[top_of_stack] * ((index - stack[-1] - 1) if stack else index)) max_area = max(max_area, area) return max_area if __name__ == "__main__": # Add your test cases here print(solution(5, [1, 2, 3, 4, 5]) == 9)

58.还原原始字符串#

Python代码#

Copy
def solution(str1): def can_generate(s, target): """检查字符串s是否能通过操作生成目标字符串target""" current = s used = {current} q = [current] while q and len(q[0]) <= len(target): current = q.pop(0) if current == target: return True # 尝试所有可能的K for k in range(len(current)): next_str = current + current[k:] if len(next_str) <= len(target) and next_str not in used: if target.startswith(next_str): used.add(next_str) q.append(next_str) return False def get_all_prefixes(s): """获取字符串的所有可能前缀""" result = [] for i in range(1, len(s) + 1): prefix = s[:i] if can_generate(prefix, s): result.append(prefix) return result # 获取所有可能的前缀 possible_prefixes = get_all_prefixes(str1) # 如果没有找到可能的前缀,返回原字符串 if not possible_prefixes: return str1 # 返回最短的可能前缀 return min(possible_prefixes, key=len) if __name__ == "__main__": # 测试用例 test_cases = [ "abbabbbabb", # "ab" "abbbabbbb", # "ab" "jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan", # "jiaban" "selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect", # "select" "discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss", # "discus" "lflsdjlskjfl" # "lflsdjlskjfl" ] expected_results = [ "ab", "ab", "jiaban", "select", "discus", "lflsdjlskjfl" ] for i, test_case in enumerate(test_cases): result = solution(test_case) print(f"Test case {i + 1}: {result == expected_results[i]}")

69.兔群繁殖之谜(原64.兔生兔)#

原问题描述#

  • 如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第 n 个月能繁殖成多少对兔子?(举例,第1个月是1对兔子,第2个月是2对兔子)

输入格式#

  • 数字

输出格式#

  • 数字

输入样例#

  • 5

输出样例#

  • 8

数据范围#

  • [1, 75]

测试数据集#

  • 样例1
    • 输入:5
    • 输出:8
  • 样例2
    • 输入:1
    • 输出:1
  • 样例3
    • 输入:15
    • 输出:987
  • 样例4
    • 输入:50
    • 输出:20365011074

题目解析#

线性dp

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll f[80]; ll solution(int A) { memset(f , 0 , sizeof f); f[0] = f[1] = 1; for(int i = 2 ; i <= A ; i ++) f[i] = f[i - 1] + f[i - 2]; return f[A]; } int main() { // Add your test cases here cout << (solution(5) == 8) << endl; cout << (solution(1) == 1) << endl; cout << (solution(15) == 987) << endl; cout << (solution(50) == 20365011074) << endl; return 0; }

Python代码#

Copy
def solution(A): f = [0] * (A + 1) # 创建一个大小为 A + 1 的数组 f[0] = f[1] = 1 # 基础情况,f(0) 和 f(1) 都为 1 for i in range(2, A + 1): f[i] = f[i - 1] + f[i - 2] # 动态规划状态转移 return f[A] # 返回第 A 个斐波那契数 if __name__ == "__main__": # Add your test cases here print(solution(5) == 8) print(solution(1) == 1) print(solution(15) == 987) print(solution(50) == 20365011074)

71.完美整数#

Python代码#

Copy
def judge(x): s = set() while(x): s.add(x % 10) x = x // 10 return len(s) == 1 def solution(x, y): count = 0 for i in range(x , y + 1): if(judge(i)): count += 1 return count if __name__ == "__main__": # Add your test cases here print(solution(1, 10) == 9) print(solution(2, 22) == 10)

74.小M的多任务下载器挑战#

Python代码#

Copy
def solution(n, array): events = [] for a in array: start = a[0] cte = a[1] end = start + cte events.append((start, 1)) events.append((end, -1)) # 排序时,时间点相同的情况下,结束事件优先 events.sort(key=lambda x: (x[0], x[1])) max_count = 0 current_count = 0 for e in events: current_count += e[1] if current_count > max_count: max_count = current_count return max_count if __name__ == "__main__": # Add your test cases here print( solution(2, [[1,2], [2,3]]) == 2 ) print( solution(4, [[1,2], [2,3],[3,5], [4,3]]) == 3 )

76.小M的弹子游戏机挑战#

Python代码#

Copy
from collections import deque def solution(n, m, array): result = [0] * m for j in range(m): stack = deque() if array[0][j] == -1: stack.appendleft((0, j, 0)) else: stack.appendleft((0, j, array[0][j])) while stack: high, width, totalScore = stack.popleft() if high == n - 1: if totalScore + array[high][width] > result[width]: result[width] = totalScore + array[high][width] continue if array[high][width] == -1: if width > 0: # 确保不超出左边界 stack.appendleft((high + 1, width - 1, totalScore)) if width < m - 1: # 确保不超出右边界 stack.appendleft((high + 1, width + 1, totalScore)) else: stack.appendleft((high + 1, width, totalScore + array[high][width])) maxScore = 0 for score in result: if score > maxScore: maxScore = score return maxScore if __name__ == "__main__": # Add your test cases here print(solution(3, 3, [[-1, 0, -1], [100, 0, 0], [0, 50, 70]]) == 50) print(solution(4, 3, [[-1, 0, -1], [0, -1, 0], [50, 100, 70], [80, 200, 50]]) == 130)

77.小M的光明之魂速通挑战#

Python代码#

Copy
def solution(n, m, boss, array): used = [False] * n return dfs(boss, array, used, 0) def dfs(boss, array, used, index): if index == len(boss): return 0 max_kill = 0 for i in range(len(array)): if not used[i] and (array[i][0] == boss[index] or array[i][1] == boss[index]): used[i] = True kills = 1 + dfs(boss, array, used, index + 1) used[i] = False if kills > max_kill: max_kill = kills return max_kill if __name__ == "__main__": # Add your test cases here print(solution(3, 5, [1, 2, 3, 4, 5], [[1, 2], [3, 2], [4, 5]]) == 2) print(solution(3, 5, [4, 3, 2, 1, 5], [[1, 2], [3, 2], [4, 5]]) == 2)

78.小M的能力选择挑战#

Python代码#

Copy
def solution(n, g, s, abilities): max_attack = [0] dfs(n, g, s, 0, 0, abilities, max_attack) return max_attack[0] def dfs(n, g, s, current_attack, current_index, abilities, max_attack): if current_index == n: if current_attack > max_attack[0]: max_attack[0] = current_attack return dfs(n, g, s, current_attack, current_index + 1, abilities, max_attack) cost, speed_change, attack_change = abilities[current_index] if g >= cost and s + speed_change >= 0: dfs(n, g - cost, s + speed_change, current_attack + attack_change, current_index + 1, abilities, max_attack) if __name__ == "__main__": # Add your test cases here test1 = [ [71, 51, 150], [40, 50, 100], [40, 50, 100], [30, 30, 70], [30, 30, 70], [30, 30, 70], ] print(solution(6, 100, 100, test1) == 240) test1 = [ [71, -51, 150], [40, -50, 100], [40, -50, 100], [30, -30, 70], [30, -30, 70], [30, -30, 70], ] print(solution(6, 100, 100, test1) == 210)

84.线上报警问题分类#

Python代码#

Copy
def solution(n, m, q, arrayN, arrayQ): # 存储每个用户的实验命中情况 user_experiments = [] # 遍历每个用户,将其命中的实验存储在集合中 for user in arrayN: experiments = set(user[1:]) user_experiments.append(experiments) # 存储每次询问的结果 results = [] # 遍历每次询问 for query in arrayQ: # 初始化符合条件的用户数量 count = 0 # 遍历每个用户 for user_exp in user_experiments: # 检查用户是否符合当前询问的条件 if check_user_matches_query(user_exp, query): count += 1 # 将符合条件的用户数量添加到结果列表中 results.append(count) return results # 检查用户是否符合当前询问的条件 def check_user_matches_query(user_exp, query): # 遍历询问中的每个条件 for exp in query[1:]: if exp > 0: # 如果实验编号为正数,检查用户是否命中该实验 if exp not in user_exp: return False else: # 如果实验编号为负数,检查用户是否未命中该实验 if -exp in user_exp: return False return True if __name__ == "__main__": # Add your test cases here print( solution( 3, 3, 3, [[2, 1, 2], [2, 2, 3], [2, 1, 3]], [[2, 1, -2], [2, 2, -3], [2, 3, -1]], ) == [1, 1, 1] )

86.版本号比较#

Python代码#

Copy
from itertools import zip_longest def solution(version1, version2): # 将版本号分割成修订号列表 v1_parts = version1.split('.') v2_parts = version2.split('.') # 逐个比较修订号 for v1_part, v2_part in zip_longest(v1_parts, v2_parts, fillvalue='0'): # 将修订号转换为整数 v1_num = int(v1_part) v2_num = int(v2_part) # 比较修订号 if v1_num > v2_num: return 1 elif v1_num < v2_num: return -1 # 如果所有修订号都相等,返回 0 return 0 if __name__ == "__main__": # Add your test cases here print(solution("0.1", "1.1") == -1) print(solution("1.0.1", "1") == 1) print(solution("7.5.2.4", "7.5.3") == -1) print(solution("1.0", "1.0.0") == 0)

87.游戏队友搜索#

Python代码#

Copy
def solution(id, num, array): player_games = {} for record in array: player, game = record[0], record[1] if player not in player_games: player_games[player] = set() player_games[player].add(game) target_games = player_games.get(id, set()) result = [] for player, games in player_games.items(): if player == id: continue count = len(games.intersection(target_games)) if count >= 2: result.append(player) result.sort() return result if __name__ == "__main__": # Add your test cases here print( solution( 1, 10, [ [1, 1], [1, 2], [1, 3], [2, 1], [2, 4], [3, 2], [4, 1], [4, 2], [5, 2], [5, 3], ], ) == [4, 5] )

88.字符串字符类型排序问题#

Python代码#

Copy
def solution(inp): # 初始化列表来存储字母和数字 letters = [] digits = [] question_marks = [] # 遍历字符串,将字母和数字分别存储到列表中,并记录问号的位置 for i, char in enumerate(inp): if char.isalpha(): letters.append(char) elif char.isdigit(): digits.append(char) else: question_marks.append(i) # 对字母列表按字典序从小到大排序 letters.sort() # 对数字列表按从大到小排序 digits.sort(reverse=True) # 初始化结果字符串 result = [] # 再次遍历字符串,根据字符类型从相应的列表中取出排序后的字符,并插入到结果字符串中 letter_index = 0 digit_index = 0 for i, char in enumerate(inp): if i in question_marks: result.append('?') elif char.isalpha(): result.append(letters[letter_index]) letter_index += 1 elif char.isdigit(): result.append(digits[digit_index]) digit_index += 1 # 将结果列表转换为字符串并返回 return ''.join(result) if __name__ == "__main__": # Add your test cases here print(solution("12A?zc") == "21A?cz") print(solution("1Ad?z?t24") == "4Ad?t?z21") print(solution("???123??zxy?") == "???321??xyz?")

96.找出最长的神奇数列#

Python代码#

Copy
def solution(inp): max_length = 0 max_start = 0 for i in range(len(inp)): # 检查从 i 开始的子序列是否是神奇数列 length = 1 while i + length < len(inp) and inp[i + length] != inp[i + length - 1]: length += 1 # 如果长度大于等于3,更新最长神奇数列的信息 if length >= 3: if length > max_length: max_length = length max_start = i # 返回最长的神奇数列 return inp[max_start:max_start + max_length] if __name__ == "__main__": # Add your test cases here print(solution("0101011101") == "010101")

100.优秀项目组初选评比#

Python代码#

Copy
def solution(m: int, n: int, a: list) -> int: # 对得分列表进行排序 a.sort() # 初始化最小分数线为 -1 min_x = -1 # 反向遍历排序后的列表 for i in range(len(a) - 1, -1, -1): # 尝试当前得分作为分数线 x x = a[i] # 计算得分大于 x 的项目组数量 count = len(a) - (i + 1) # 检查 count 是否在 [m, n] 之间 if m <= count <= n and m <= len(a) - count <= n: # 更新最小分数线 min_x = x print(min_x) return min_x if __name__ == '__main__': print(solution(2, 3, [1, 2, 3, 5, 6, 4]) == 3) print(solution(1, 2, [7, 8, 9, 3, 5]) == -1) print(solution(1, 4, [7, 8, 9, 3, 5]) == 3)

103.完美偶数计数#

Python代码#

Copy
def is_perfect_even(num: int, l: int, r: int) -> bool: """ 判断一个数是否是完美偶数 Args: num: 要判断的数 l: 区间左端点 r: 区间右端点 Returns: bool: 是否是完美偶数 """ # 判断是否为偶数 if num % 2 != 0: return False # 判断是否在区间[l,r]内 return l <= num <= r def solution(n: int, l: int, r: int, a: list) -> int: """ 计算数组中完美偶数的个数 Args: n: 数组长度 l: 区间左端点 r: 区间右端点 a: 输入数组 Returns: int: 完美偶数的个数 """ # 统计满足条件的数的个数 count = 0 for num in a: if is_perfect_even(num, l, r): count += 1 return count if __name__ == '__main__': # 测试用例 print(solution(5, 3, 8, [1, 2, 6, 8, 7]) == 2) # True,6和8是完美偶数 print(solution(4, 10, 20, [12, 15, 18, 9]) == 2) # True,12和18是完美偶数 print(solution(3, 1, 10, [2, 4, 6]) == 3) # True,2,4,6都是完美偶数 # 额外测试用例 print(solution(3, 1, 5, [2, 3, 4]) == 2) # True,2和4是完美偶数 print(solution(4, 10, 15, [9, 11, 13, 15]) == 0) # True,没有完美偶数 print(solution(2, 1, 100, [2, 4]) == 2) # True,都是完美偶数

123.小C点菜问题#

Python代码#

Copy
def solution(m: int, w: list) -> int: # 初始化价格计数字典 price_count = {} # 遍历每道菜的价格 for price in w: if price <= m: # 如果价格在允许范围内,增加计数 if price in price_count: price_count[price] += 1 else: price_count[price] = 1 # 找出数量最多的那种价格的菜的数量 max_count = 0 for count in price_count.values(): if count > max_count: max_count = count return max_count if __name__ == '__main__': print(solution(6, [2, 3, 3, 6, 6, 6, 9, 9, 23]) == 3) print(solution(4, [1, 2, 4, 4, 4]) == 3) print(solution(5, [5, 5, 5, 5, 6, 7, 8]) == 4)

138.小C的排列询问#

Python代码#

Copy
def solution(n: int, a: list, x: int, y: int) -> bool: # 遍历数组,检查每一对相邻的元素 for i in range(n - 1): # 检查当前元素和下一个元素是否分别是 x 和 y if (a[i] == x and a[i + 1] == y) or (a[i] == y and a[i + 1] == x): return True # 如果没有找到相邻的 x 和 y,返回 False return False if __name__ == '__main__': print(solution(4, [1, 4, 2, 3], 2, 4) == True) print(solution(5, [3, 4, 5, 1, 2], 3, 2) == False) print(solution(6, [6, 1, 5, 2, 4, 3], 5, 2) == True)

153.小D的 abc 变换问题#

Java代码#

Copy
public class Main { public static String solution(String s, int k) { // 初始化 StringBuilder StringBuilder current = new StringBuilder(s); // 重复变换 k 次 for (int i = 0; i < k; i++) { StringBuilder next = new StringBuilder(); // 遍历当前字符串中的每个字符 for (int j = 0; j < current.length(); j++) { char c = current.charAt(j); // 根据变换规则生成新的字符串 if (c == 'a') { next.append("bc"); } else if (c == 'b') { next.append("ca"); } else if (c == 'c') { next.append("ab"); } } // 更新当前字符串为新生成的字符串 current = next; } // 返回最终结果 return current.toString(); } public static void main(String[] args) { System.out.println(solution("abc", 2).equals("caababbcbcca")); System.out.println(solution("abca", 3).equals("abbcbccabccacaabcaababbcabbcbcca")); System.out.println(solution("cba", 1).equals("abcabc")); } }

154.小S的倒排索引#

Java代码#

Copy
import java.util.*; public class Main { public static List<Integer> solution(List<Integer> a, List<Integer> b) { // 使用 HashSet 存储 a 中的元素 Set<Integer> setA = new HashSet<>(a); // 使用 ArrayList 存储交集结果 List<Integer> result = new ArrayList<>(); // 遍历 b,检查元素是否在 setA 中 for (int num : b) { if (setA.contains(num)) { result.add(num); } } // 对结果列表进行排序,按从大到小的顺序 result.sort((x, y) -> y - x); return result; } public static void main(String[] args) { System.out.println(solution(Arrays.asList(1, 2, 3, 7), Arrays.asList(2, 5, 7)).equals(Arrays.asList(7, 2))); System.out.println(solution(Arrays.asList(1, 4, 8, 10), Arrays.asList(2, 4, 8, 10)).equals(Arrays.asList(10, 8, 4))); System.out.println(solution(Arrays.asList(3, 5, 9), Arrays.asList(1, 4, 6)).equals(Collections.emptyList())); System.out.println(solution(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3)).equals(Arrays.asList(3, 2, 1))); } }

155.小E的射击训练#

Python代码#

Copy
def solution(x: int, y: int) -> int: # 计算射击点到靶心的距离 distance = (x * x + y * y) ** 0.5 # 如果距离大于10,超出所有环,得0分 if distance > 10: return 0 # 根据距离确定所在环数 # 使用向上取整,因为距离正好在圆上时应该算作外环 ring = int(distance + 0.99999) # 使用这种方式处理浮点数精度问题 # 计算得分:11减去环数 score = 11 - ring return score if __name__ == '__main__': # 测试样例 print(solution(1, 0) == 10) # True,距离1,在第1环内 print(solution(1, 1) == 9) # True,距离√2≈1.414,在第2环内 print(solution(0, 5) == 6) # True,距离5,在第5环内 print(solution(3, 4) == 6) # True,距离5,在第5环内 # 额外测试用例 print(solution(0, 0) == 10) # 靶心 print(solution(10, 0) == 1) # 第10环边界 print(solution(7, 7) == 1) # 距离约9.899,在第10环内 print(solution(8, 8) == 0) # 距离约11.314,超出所有环

171.小M的奶酪问题#

Python代码#

Copy
def solution(A: int, B: int) -> str: C = B - A ans = str(C) + "/" + str(B) # write code here return ans if __name__ == '__main__': print(solution(2, 7) == "5/7") print(solution(1, 3) == "2/3") print(solution(3, 5) == "2/5")

224.小U的数字插入问题#

Java代码#

Copy
public class Main { public static int solution(int a, int b) { // 将数字 a 和 b 转换为字符串 String strA = Integer.toString(a); String strB = Integer.toString(b); // 初始化最大结果 String maxResult = strA; // 遍历字符串 a 的每个位置 for (int i = 0; i <= strA.length(); i++) { // 尝试将 b 插入到位置 i String newResult = strA.substring(0, i) + strB + strA.substring(i); // 比较新结果和当前最大结果 if (newResult.compareTo(maxResult) > 0) { maxResult = newResult; } } // 将最大结果转换回整数并返回 return Integer.parseInt(maxResult); } public static void main(String[] args) { System.out.println(solution(76543, 4) == 765443); System.out.println(solution(1, 0) == 10); System.out.println(solution(44, 5) == 544); System.out.println(solution(666, 6) == 6666); } }

226.小T的密码变换规则#

Python代码#

Copy
def solution(s: str) -> str: # 创建字母到数字的映射字典 letter_to_digit = { 'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5', 'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7', 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9' } result = [] for char in s: if char.isupper(): # 大写字母转换为小写字母,再跳到前一个字母 if char == 'A': prev_char = 'z' else: prev_char = chr(ord(char.lower()) - 1) result.append(letter_to_digit[prev_char]) elif char.islower(): # 小写字母直接查找映射 result.append(letter_to_digit[char]) else: # 非字母字符保持不变 result.append(char) # 将结果列表转换为字符串 return ''.join(result) if __name__ == '__main__': print(solution(s="LIming0701") == '5464640701') print(solution(s="PassW0rd") == '62778073') print(solution(s="helloWORLD123") == '4355686752123')

253.组成字符串ku的最大次数#

Python代码#

Copy
def solution(s: str) -> int: # 将字符串转换为小写 s = s.lower() # 初始化计数器 count_k = 0 count_u = 0 # 遍历字符串,统计 'k' 和 'u' 的数量 for char in s: if char == 'k': count_k += 1 elif char == 'u': count_u += 1 # 组成 "ku" 的最大次数是 count_k 和 count_u 中的较小值 return min(count_k, count_u) if __name__ == '__main__': print(solution("AUBTMKAxfuu") == 1) print(solution("KKuuUuUuKKKKkkkkKK") == 6) print(solution("abcdefgh") == 0)

254.游戏排名第三大的分数#

Python代码#

Copy
def solution(n: int, nums: list) -> int: # 使用集合去重 unique_scores = set(nums) # 将集合转换为列表并排序 sorted_scores = sorted(unique_scores, reverse=True) # 判断列表长度并返回结果 if len(sorted_scores) >= 3: return sorted_scores[2] # 返回第三大的分数 else: return sorted_scores[0] # 返回最大的分数 if __name__ == '__main__': print(solution(3, [3, 2, 1]) == 1) print(solution(2, [1, 2]) == 2) print(solution(4, [2, 2, 3, 1]) == 1)

255.最少步数归零问题#

Python代码#

Copy
def min_steps_for_number(num: int) -> int: """计算单个数字归零需要的最少步数""" # 如果是0,不需要任何步数 if num == 0: return 0 # 如果是个位数,只需要一步 if num < 10: return 1 # 将数字转为字符串以便处理每一位 str_num = str(num) length = len(str_num) # 对于每个非0数字,我们都需要一步来删除它 # 计算非0数字的个数 non_zero_count = sum(1 for digit in str_num if digit != '0') return non_zero_count def solution(n: int, a: list) -> int: """计算数组中所有数字归零的最少步数总和""" # 对数组中每个数字计算最少步数并求和 total_steps = 0 for num in a: steps = min_steps_for_number(num) total_steps += steps return total_steps if __name__ == '__main__': # 测试样例 print(solution(5, [10, 13, 22, 100, 30]) == 7) # True print(solution(3, [5, 50, 505]) == 4) # True print(solution(4, [1000, 1, 10, 100]) == 4) # True # 额外测试用例 print(solution(1, [0]) == 0) # 测试0的情况 print(solution(2, [9, 99]) == 3) # 测试不同位数的情况 print(solution(1, [101]) == 2) # 测试中间有0的情况

256.红包运气排行榜#

Python代码#

Copy
def solution(n: int, s: list, x: list) -> list: # 使用字典记录每个人的总抢红包金额和第一次抢红包的顺序 total_amount = {} first_index = {} for i in range(n): name = s[i] amount = x[i] # 更新总金额 if name in total_amount: total_amount[name] += amount else: total_amount[name] = amount first_index[name] = i # 记录第一次抢红包的顺序 # 将字典转换为元组列表 people = [(name, total_amount[name], first_index[name]) for name in total_amount] # 对这个元组列表进行排序,排序规则是先按金额降序排序,如果金额相同,则按第一次抢红包的顺序升序排序 people.sort(key=lambda p: (-p[1], p[2])) # 提取排序后的名字列表作为结果 return [p[0] for p in people] if __name__ == '__main__': print(solution(4, ["a", "b", "c", "d"], [1, 2, 2, 1]) == ['b', 'c', 'a', 'd']) print(solution(3, ["x", "y", "z"], [100, 200, 200]) == ['y', 'z', 'x']) print(solution(5, ["m", "n", "o", "p", "q"], [50, 50, 30, 30, 20]) == ['m', 'n', 'o', 'p', 'q'])

294.选择题反选效果分析#

Python代码#

Copy
def solution(n: int, s: str, t: str) -> str: # 初始化原始答案和反选后答案的正确数量 correct_count = 0 correct_count_after_flip = 0 # 遍历答案字符串 for i in range(n): # 计算原始答案的正确数量 if s[i] == t[i]: correct_count += 1 # 计算反选后答案的正确数量 if s[i] != t[i]: correct_count_after_flip += 1 # 比较原始答案和反选后答案的正确数量 if correct_count_after_flip > correct_count: return "yes" elif correct_count_after_flip == correct_count: return "draw" else: return "no" if __name__ == '__main__': print(solution(2, "AB", "AA") == 'draw') print(solution(3, "BAA", "ABB") == 'yes') print(solution(4, "ABAB", "BABA") == 'yes')

299.0,1背包最大价值问题#

Python代码#

Copy
def solution(n: int, weights: list, values: list, m: int) -> int: # 初始化dp数组 dp = [[0] * (m + 1) for _ in range(n + 1)] # 填充dp数组 for i in range(1, n + 1): for j in range(1, m + 1): if j >= weights[i - 1]: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]) else: dp[i][j] = dp[i - 1][j] # 返回最大价值 return dp[n][m] if __name__ == '__main__': print(solution(n = 3, weights = [2, 1, 3], values = [4, 2, 3], m = 3) == 6) print(solution(n = 4, weights = [1, 2, 3, 2], values = [10, 20, 30, 40], m = 5) == 70) print(solution(n = 2, weights = [1, 4], values = [5, 10], m = 4) == 10)

301.a替换函数#

Python代码#

Copy
def solution(s: str) -> str: res = "" for i in s: # 使用 s 而不是 str if i == "a": res += "%100" # 使用 + 操作符连接字符串 else: res += i # 使用 + 操作符连接字符串 return res if __name__ == '__main__': print(solution(s="abcdwa") == '%100bcdw%100') print(solution(s="banana") == 'b%100n%100n%100') print(solution(s="apple") == '%100pple')

后面不给题号了,太难数了

二进制反码转换问题#

Python代码#

Copy
def solution(N: int) -> int: if N == 0: return 1 # 将十进制数转换为二进制字符串 binary_str = bin(N)[2:] # 去掉前缀 '0b' # 计算反码 inverted_binary_str = ''.join('1' if bit == '0' else '0' for bit in binary_str) # 将反码转换回十进制 result = int(inverted_binary_str, 2) return result if __name__ == '__main__': print(solution(N=5) == 2) print(solution(N=10) == 5) print(solution(N=0) == 1)

充电总时间计算#

Python代码#

Copy
def solution(n: int, x: int, a: list) -> str: # 初始化总充电时间为0 total_time = 0.0 # 遍历每部电脑的电池容量 for battery in a: # 计算每部电脑的充电时间 charging_time = battery / (4 * x) # 累加充电时间 total_time += charging_time # 格式化输出总充电时间 return f"{total_time:.2f}" if __name__ == '__main__': print(solution(4, 1, [2, 3, 4, 5]) == '3.50') print(solution(3, 2, [4, 6, 8]) == '2.25') print(solution(2, 1, [10, 5]) == '3.75')

删除路径后的最短路问题#

Python代码#

Copy
import math from heapq import heappush, heappop def solution(n: int, s: int, t: int, x: list, y: list) -> str: # 计算两点之间的欧几里得距离 def calculate_distance(x1, y1, x2, y2): return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) # 构建邻接矩阵 dist = [[0] * n for _ in range(n)] for i in range(n): for j in range(n): if i != j: dist[i][j] = calculate_distance(x[i], y[i], x[j], y[j]) # Dijkstra算法实现 def dijkstra(start, end): # 如果起点等于终点,我们需要找到一个最小的环 if start == end: min_cycle = float('inf') # 尝试通过每个中间点构建一个环 for mid in range(n): if mid != start-1: # 从起点到中间点,再返回起点的距离 cycle_dist = dist[start-1][mid] + dist[mid][start-1] min_cycle = min(min_cycle, cycle_dist) return min_cycle # 初始化距离数组和访问标记 distances = [float('inf')] * n distances[start-1] = 0 pq = [(0, start-1)] visited = set() while pq: d, curr = heappop(pq) if curr in visited: continue visited.add(curr) if curr == end-1: return d # 遍历所有相邻节点 for next_node in range(n): # 跳过已访问的节点和不允许的直接路径 if next_node in visited or (curr == s-1 and next_node == t-1) or (curr == t-1 and next_node == s-1): continue new_dist = d + dist[curr][next_node] if new_dist < distances[next_node]: distances[next_node] = new_dist heappush(pq, (new_dist, next_node)) return float('inf') # 计算最短路径并格式化结果 result = dijkstra(s, t) return "{:.2f}".format(result) if __name__ == '__main__': # 原有测试用例 print(solution(5, 1, 5, [17253, 25501, 28676, 30711, 18651], [15901, 15698, 32041, 11015, 9733]) == '17333.65') print(solution(4, 2, 4, [5000, 12000, 8000, 14000], [3000, 9000, 1000, 4000]) == '15652.48') print(solution(6, 3, 6, [20000, 22000, 24000, 26000, 28000, 30000], [15000, 13000, 11000, 17000, 19000, 21000]) == '11772.70') # 新增测试用例:起点终点相同的情况 print(solution(10, 2, 2, [11,3,5,6,2,4,15,14,16,8], [5,8,7,14,8,10,5,4,2,9]) == '2.00')

判断回旋镖的存在#

Python代码#

Copy
def solution(points: list) -> bool: # 检查三点是否相同 if points[0] == points[1] or points[1] == points[2] or points[0] == points[2]: return False # 检查三点是否共线 x1, y1 = points[0] x2, y2 = points[1] x3, y3 = points[2] # 使用斜率公式判断三点是否共线 if (y2 - y1) * (x3 - x2) == (y3 - y2) * (x2 - x1): return False return True if __name__ == '__main__': print(solution(points=[[1, 1], [2, 3], [3, 2]]) == True) print(solution(points=[[1, 1], [2, 2], [3, 3]]) == False) print(solution(points=[[0, 0], [1, 1], [1, 0]]) == True)

判断数组是否单调#

Python代码#

Copy
def solution(nums: list) -> bool: # 初始化标志位 is_increasing = False is_decreasing = False # 遍历数组 for i in range(len(nums) - 1): if nums[i] < nums[i + 1]: is_increasing = True elif nums[i] > nums[i + 1]: is_decreasing = True # 如果同时满足递增和递减,则数组不是单调的 if is_increasing and is_decreasing: return False # 如果遍历结束,数组是单调的 return True if __name__ == '__main__': print(solution(nums=[1, 2, 2, 3]) == True) print(solution(nums=[6, 5, 4, 4]) == True) print(solution(nums=[1, 3, 2, 4, 5]) == False)

字符串解码问题#

Python代码#

Copy
from typing import Counter def solution(N: int, S: str) -> str: p = Counter() # 直接设置特定字符的映射关系 p['x'] = 'y' p['y'] = 'x' p['a'] = 'b' p['b'] = 'a' res = "" for i in S: # 如果字符在映射表中,使用映射后的字符,否则保持不变 res += p.get(i, i) return res if __name__ == '__main__': print(solution(N = 5, S = "xaytq") == 'ybxtq') print(solution(N = 6, S = "abcxyz") == 'bacyxz') print(solution(N = 3, S = "zzz") == 'zzz')

小F的矩阵值调整#

Python代码#

Copy
def solution(a: list) -> int: # write code here res = [] for i in a: it = [] for j in i: if(j % 2 == 0): it.append(j * 3) else : it.append(j) res.append(it) return res if __name__ == '__main__': print(solution([[1, 2, 3], [4, 5, 6]]) == [[1, 6, 3], [12, 5, 18]]) print(solution([[7, 8, 9], [10, 11, 12]]) == [[7, 24, 9], [30, 11, 36]]) print(solution([[2, 4], [6, 8]]) == [[6, 12], [18, 24]])

数字字符串中圆圈的数量计算#

Python代码#

Copy
from typing import Counter def solution(s: str) -> int: p = Counter() p["0"] = 1 p["6"] = 1 p["9"] = 1 p["8"] = 2 res = 0 for i in s: res += p[i] return res if __name__ == '__main__': print(solution(s = "1234567890") == 5) print(solution(s = "8690") == 5) print(solution(s = "1111") == 0)

构造特定数组的逆序拼接#

Python代码#

Copy
def solution(n: int) -> list: result = [] for i in range(1, n + 1): # 生成从 n 到 i 的逆序列表 reverse_list = list(range(n, i - 1, -1)) # 将这个逆序列表追加到 result 中 result.extend(reverse_list) return result if __name__ == '__main__': print(solution(3) == [3, 2, 1, 3, 2, 3]) print(solution(4) == [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]) print(solution(5) == [5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5])

比赛配对问题#

Python代码#

Copy
def solution(n: int) -> int: pairs = 0 while n > 1: if n % 2 == 0: pairs += n // 2 n = n // 2 else: pairs += (n - 1) // 2 n = (n - 1) // 2 + 1 return pairs if __name__ == '__main__': print(solution(7) == 6) print(solution(14) == 13) print(solution(1) == 0)

蛇形填充n阶方阵#

Python代码#

Copy
def solution(n: int) -> list: # 创建n×n的方阵,初始化为0 matrix = [[0] * n for _ in range(n)] def fill_border(start_num, start_row, start_col, size): """ 填充当前边界 start_num: 开始的数字 start_row, start_col: 开始的位置 size: 当前边框的大小 """ if size <= 0: return current = start_num # 如果只剩一个格子 if size == 1: matrix[start_row][start_col] = current return # 填充上边 for col in range(start_col + size - 1, start_col - 1, -1): matrix[start_row][col] = current current += 1 # 填充右边 for row in range(start_row + 1, start_row + size): matrix[row][start_col] = current current += 1 # 填充下边(如果存在) if size > 1: for col in range(start_col + 1, start_col + size): matrix[start_row + size - 1][col] = current current += 1 # 填充左边(如果存在) if size > 1: for row in range(start_row + size - 2, start_row, -1): matrix[row][start_col + size - 1] = current current += 1 # 递归填充内部 if size > 2: fill_border(current, start_row + 1, start_col + 1, size - 2) # 从最外层开始填充 fill_border(1, 0, 0, n) res = [[0] * n for _ in range(n)] for i in range(n): for j in range(n): res[i][j] = matrix[n - j - 1][n - i - 1] return res def print_matrix(matrix): """辅助函数:打印矩阵,便于调试""" for row in matrix: print(' '.join(f'{x:2d}' for x in row)) if __name__ == '__main__': # 测试用例 test_cases = [4, 5, 3] expected_results = [ [[10, 11, 12, 1], [9, 16, 13, 2], [8, 15, 14, 3], [7, 6, 5, 4]], [[13, 14, 15, 16, 1], [12, 23, 24, 17, 2], [11, 22, 25, 18, 3], [10, 21, 20, 19, 4], [9, 8, 7, 6, 5]], [[7, 8, 1], [6, 9, 2], [5, 4, 3]] ] for i, n in enumerate(test_cases): result = solution(n) print(f"\n测试用例 n={n}:") print_matrix(result) print("验证结果:", result == expected_results[i])
posted @   她说戴了不算給  阅读(1896)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
目录
点击右上角即可分享
微信分享提示