第十五届蓝桥杯大赛软件赛省赛-Python大学A组

前言

第一次参加算法,一周速通了一波,被薄纱。

我的wp一派胡言,大家看个乐就行。

试题A:拼正方形

大概率错了

#小蓝正在玩拼图游戏,他有7385137888721个2×2的方块和10470245个1×1的方块,
# 他需要从中挑出一些来拼出一个正方形,比如用3个2×2和4 个1×1的方块可以拼出一个4×4的正方形,
# 用9个2×2的方块可以拼出一个6×6的正方形,请问小蓝能拼成的最大的正方形的边长为多少。
import math
da = 7385137888721
xiao = 10470245
xbd = xiao / 4
sum = da + xbd
n = int(sum)
x = math.sqrt(n)
print(x)
print(type(x)) #开根号后的类型为float
print(x*2)

试题B:召唤数学精灵

没跑出来

#A(n)是将从1到n的所有数字进行累加求和,即:A(n)=1+2+···+n。
#B(n)则是将从1到n的所有数字进行累乘求积,即:B(n)=1×2×···×n。
#当某个数字i满足A(i)−B(i)能被100整除时,打印出来
#寻找在1到2024041331404202之间有多少个数字i
def A(n):
    return sum(range(1, n + 1))
def B(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result
def find_numbers(start, end):
    count = 0
    for i in range(start, end + 1):
        if (A(i) - B(i)) % 100 == 0:
            # print("满足条件的数字:", i)
            count += 1
    return count
start = 1
end = 2024041331404202
count = find_numbers(start, end)
print("在范围 {} 到 {} 之间有 {} 个数字满足条件。".format(start, end, count))


试题C:数字诗意

唯一一个有点自信

#某日,小蓝静坐书桌前,目光所及,展现着n个数字,它们依次为a1,a2,...,an,
#熠熠生辉。小蓝悟到,如果一个数能够以若干个(至少两个)连续的正整数相加表示,
#那么它就蕴含诗意。例如,数字6就蕴含诗意,因为它可以表示为1+2+3。而8则缺乏诗意,
#因为它无法用连续的正整数相加表示。
#小蓝希望他面前的所有数字都蕴含诗意,
#为此,他决定从这n个数字中删除一部分。请问,小蓝需要删除多少个数字,才能使剩下的数字全部蕴含诗意?
def dn(n, nums):
    count = 0
    for i in range(n):
        if not sumw(nums[i]):
            count += 1
    return count
def sumw(num):
    # 找到连续的正整数之和是否等于num
    total = 0
    i = 1
    while total < num:
        total += i
        i += 1
    return total == num
# 读取输入
n = int(input())
nums = list(map(int, input().split()))
# 计算需要删除的数字个数
result = dn(n, nums)
# 输出结果
print(result)

试题D:回文数组

强行拼check

#小蓝在无聊时随机生成了一个长度为n的整数数组,数组中的第i个数为ai,
#他觉得随机生成的数组不太美观,想把它变成回文数组,也是就对于任意i∈[1,n]满足ai=an−i+1。
#小蓝一次操作可以指定相邻的两个数,将它们一起加1或减1;也可以只指定一个数加1或减1,
#请问他最少需要操作多少次能把这个数组变成回文数组?
def min_operations(n, nums):
    # 计算操作次数
    operations = 0
    for i in range(n // 2):
        operations += abs(nums[i] - nums[n - i - 1])
    return operations

# 读取输入
n = int(input())
nums = list(map(int, input().split()))

# 计算最小操作次数
result = min_operations(n, nums)

# 输出结果
print(result // 2 + 1)  # 因为每次操作都会同时影响两个位置,所以结果需要除以2

试题E:吊坠

还是强行拼check

#小蓝想制作一个吊坠,他手上有n个长度为m的首尾相连的环形字符串{s1,s2,···,sn},
#他想用n−1条边将这n个字符串连接起来做成吊坠,要求所有的字符串连完后形成一个整体。
#连接两个字符串si,sj的边的边权为这两个字符串的最长公共子串的长度(可以按环形旋转改变起始位置,但不能翻转),
#小蓝希望连完后的这n−1条边的边权和最大,这样的吊坠他觉得最好看,请计算最大的边权和是多少。
def longestsub(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[0] * (n + 1) for in range(m + 1)]
    max
length = 0
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
                max_length = max(max_length, dp[i][j])
    return max_length

# 读取输入
n, m = map(int, input().split())
strings = [input() for in range(n)]

# 计算最大的边权和
msum = 0
for i in range(n):
    for j in range(i + 1, n):
        edge
weight = longestsub(strings[i], strings[j])
        msum += edge_weight

# 输出结果
print(msum - 2)


试题F:砍柴

第二道稍微自信一点的

#小蓝和小乔正在森林里砍柴,它们有T根长度分别为n1,n2,···,nT的木头。
#对于每个初始长度为n的木头,小蓝和小乔准备进行交替砍柴,
#小蓝先出手。每次砍柴时,若当前木头长度为x,需要砍下一截长度为p的木头,
#然后换另一个人继续砍,其中2≤p≤x且p必须为质数。当轮到某一方时x=1或x=0,
#它就没法继续砍柴,它就输了。它们会使用最优策略进行砍柴。
#请对每根木头判断是小蓝赢还是小乔赢,如果小蓝赢请输出1(数字1),如果小乔赢请输出0(数字0)。
def is_prime(n):
    if n <= 1:
        return False
    if n 2:
        return True
    if n % 2 0:
        return False
    i = 3
    while i * i <= n:
        if n % i == 0:
            return False
        i += 2
    return True

def can_win(x):
    # 如果当前木头长度为 0 或 1,当前玩家输掉游戏
    if x <= 1:
        return False
    # 找到一个符合条件的质数 p,使得对手在当前木头长度为 p 时输掉游戏
    for p in range(2, x + 1):
        if is_prime(p) and not can_win(x - p):
            return True
    return False

# 读取输入
T = int(input())
wood_lengths = [int(input()) for in range(T)]

# 判断每根木头的胜负情况
results = [1 if can
win(wood_length) else 0 for wood_length in wood_lengths]

# 输出结果
for result in results:
    print(result)


试题G:智力测试

写了一半不会了

MOD = 1000000007

def count_paths(n, m, R, C, si, sj, ti, tj):
    dp = [[0] * (m + 1) for in range(n + 1)]
    dp[si][sj] = 1

    for i in range(si, ti + 1):
        for j in range(sj, tj + 1):
            if i si and j sj:
                continue
            if R[i] > R[si] and C[j] > C[sj]:
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % MOD

    return dp[ti][tj]

# 读取输入
n, m, T = map(int, input().split())
R = [0] + list(map(int, input().split()))
C = [0] + list(map(int, input().split()))

# 处理每个问题
for
in range(T):
    si, sj, ti, tj = map(int, input().split())
    result = count_paths(n, m, R, C, si, sj, ti, tj)
    print(result)


试题H:最大异或结点

看都看不懂