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

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

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

今天看见更新\(C++\)判题了!!! 太好了

当前已经 \(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。请问一共有多少种划分方式?

备注:

  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++代码

#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。求 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 所需最小步数。

输入样例

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,有 CGAGTCGAGTCCAGTCCG 等表示法。在这些表示法中,字典序最小的称为“最小表示”。

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

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

输入描述

一段 DNA 碱基序列

输出描述

DNA 碱基序列的最小表示

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

示例 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

题目解析

线性\(dp\)

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;
}

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

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 个整数。

输入格式

输入每行一个整数 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(n^2 * m)\) \(n\)是数的个数 \(m\)是数的大小范围长度
这里\(3 \le n \le 10\) 所以不用特判,不用在意\(n^2\)的时间问题

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%的数据保证 \(M = 0, 1 <= N <= 10\)

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

100%的数据保证 \(1 <= N <= 25, 0 <= M <= N, 1 <= S <= 10^16\)

题目解析

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

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

题目解析

线性\(dp\)

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])
posted @ 2024-10-24 10:32  她说戴了不算給  阅读(1960)  评论(0)    收藏  举报