字节掘金青训营题解(持续更新,已更新至79题)
本人正在狂写赶工,不要着急,尽量会把所有题都写出来的,可能旧题目和新题目之间有差异,后续会持续更新,都给大家展示出来
题目链接
又改题目顺序了。。。。。。。。。。。。。。。。。烦躁,等有时间再重新编号吧#
今天看见更新 判题了!!! 太好了#
当前已经 题
1.数字分组求偶数和#
Python代码#
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代码#
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 代码#
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++代码#
#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 代码#
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。请问一共有多少种划分方式?
备注:
-
数组里的数字可以相等,但每个数字都是独一无二的。
比如数组 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] -
可以将所有数字都划分到同一组,使其和的个位数等于 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
题目解析#
线性
C++代码#
#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代码#
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++代码#
#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
。求 x
到 y
最少走几步。并且第一步必须是 1
,最后一步必须是 1
,从 x
到 y
最少需要多少步。
样例说明#
- 整数位置
x
为12
,另外一个整数位置y
为6
,我们需要从x
走到y
,最小的步数为:1
,2
,2
,1
,所以我们需要走4
步。 - 整数位置
x
为34
,另外一个整数位置y
为45
,我们需要从x
走到y
,最小的步数为:1
,2
,3
,2
,2
,1
,所以我们需要走6
步。 - 整数位置
x
为50
,另外一个整数位置y
为30
,我们需要从x
走到y
,最小的步数为:1
,2
,3
,4
,4
,3
,2
,1
,所以我们需要走8
步。
输入格式#
输入包含 2
个整数 x
,y
。(0<=x<=y<2^31
)
输出格式#
对于每一组数据,输出一行,仅包含一个整数,从 x
到 y
所需最小步数。
输入样例#
12 6
34 45
50 30
输出样例#
4
6
8
题目解析#
简单数学
C++代码#
#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 代码#
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
,有 CGAGTC
、GAGTCC
、AGTCCG
等表示法。在这些表示法中,字典序最小的称为“最小表示”。
输入一个长度为 n
(n <= 100
)的环状碱基序列(只包含 A
、C
、G
、T
这 4 种碱基)的一种表示法,输出该环状碱基序列的最小表示。
例如:
ATCA
的最小表示是 AATC
CGAGTC
的最小表示是 AGTCCG
输入描述#
一段 DNA 碱基序列
输出描述#
DNA 碱基序列的最小表示
备注:
n <= 100
DNA 由大写英文字母 A
、G
、C
、T
组成
示例 1
输入:ATCA
输出:AATC
示例 2
输入:CGAGTC
输出:AGTCCG
题目解析#
语法题
C++代码#
#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 代码#
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代码#
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代码#
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++ 代码#
#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++代码#
\#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++代码#
#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代码#
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++代码#
#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
题目解析#
线性
C++代码#
#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;
}
现在题目变化了,至少是
Python代码#
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 个整数。
输入格式#
输入每行一个整数 n
(2 < 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
题目解析#
枚举第一个数的大小,直接暴力验证即可 时间复杂度
这里
C++代码#
#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 代码#
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++代码#
#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代码#
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代码#
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++代码(没做高精,因为样例小,懒得做)#
#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代码#
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 代码#
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代码#
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++ 代码#
#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代码#
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代码#
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代码#
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%的数据保证
30%的数据保证
100%的数据保证
题目解析#
背包问题,空间优化+离散化
C++ 代码#
#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 代码#
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代码#
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 代码#
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.多米诺骨牌均衡状态#
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 代码#
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代码#
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代码#
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代码#
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代码#
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)#
1 1 2 2 3 3 4 5 5
输出样例(1)#
4
输入样例(2)#
0 1 0 1 2
输出样例(2)#
2
题目解析#
语法题
解法一#
C++代码#
#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代码#
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++代码#
#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代码#
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代码#
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代码#
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代码#
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
- 输入:
题目解析#
线性
C++代码#
#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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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代码#
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])
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端