2021软件类第十二届蓝桥杯国赛真题 Python组 A-E题解

Posted 风信子的猫Redamancy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021软件类第十二届蓝桥杯国赛真题 Python组 A-E题解相关的知识,希望对你有一定的参考价值。

2021软件类第十二届蓝桥杯国赛真题 Python组 A-E题解

文章目录


备战第十三届蓝桥杯国赛

试题 A: 带宽

本题总分:5分

【问题描述】

小蓝家的网络带宽是 200Mbps,请问,使用小蓝家的网络理论上每秒钟最多可以从网上下载多少 MB 的内容。

【思路分析】

这个题就比较简单了,签到题,Mbps/8就是实际速度

参考答案

25

试题 B: 纯质数

本题总分:5 分

【问题描述】

如果一个正整数只有 1 11 和它本身两个约数,则称为一个质数(又称素数)。

前几个质数是:2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , . . .

如果一个质数的所有十进制数位都是质数,我们称它为纯质数。例如:2 , 3 , 5 , 7 , 23 , 37都是纯质数,而 11 , 13 , 17 , 19 , 29 , 31 11, 13, 17, 19, 29, 31 不是纯质数。当然 1 , 4 , 35 也不是纯质数。

请问,在1 到 20210605 中,有多少个纯质数?

【思路分析】

这道题还是比较简单,最直接的想法就是循环判断,这里的1~20210605中的质数我们可以利用埃氏筛来得到

接着循环判断每一位就很快出结果了。

除此之外,我还看到一个挺好的思路,我们已经知道了0,4,6,8,9这些肯定不是质数,所以位数含这些一定不是纯质数,所以我们只会对无这些数的数进行判断是否是质数,这样可能也会更加快,不过基本思路相同。

代码code

# 埃氏筛得到1-n的质数
def get_prime(n):
    prime = [1]*(n+1)
    prime[0] = 0
    prime[1] = 0
    for i in range(2,int(n**0.5)+1):
        if prime[i] == 1:
            for j in range(2*i,n+1,i):
                prime[j] = 0
    return prime
cnt = 0
n = 20210605
prime = get_prime(n)
for i in range(1,n+1):
    if prime[i]:
        flag = True
        for j in str(i):
            j = int(j)
            if prime[j] == 0:
                flag = False
                break
        if flag:
            cnt += 1

print(cnt)

参考答案

1903

试题 C: 完全日期

本题总分:10 分

【问题描述】

如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日期。

例如:2021年6 月5 日的各位数字之和为2 + 0 + 2 + 1 + 6 + 5 = 16,而 16 是一个完全平方数,它是 4 的平方。所以2021 年 6 月 5 日是一个完全日期。

例如:2021年6 月23 日的各位数字之和为2 + 0 + 2 + 1 + 6 + 2 + 3 = 16 ,是一个完全平方数。所以2021 年6 月23 日也是一个完全日期。

请问,从2001 年1 月1 日到2021 年12 月31 日中,一共有多少个完全日期?

【思路分析】

常规日期题,模拟日期操作然后判断即可。日期,最大 8 位数,最大的和应为2 + 0 + 1 + 9 + 1 + 2 + 2 + 9 = 26,所以可以提前算出来[1,4,9,16,25]这几个数,然后直接判断即可,不必重复计算。

【代码code】

def wonderDate(year, month, day):
    date = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    year = list(map(int, list(str(year))))
    month = list(map(int, list(str(month))))
    day = list(map(int, list(str(day))))
    return sum(year) + sum(month) + sum(day) in date


year, month, day, c = 2001, 1, 1, 0
while year < 2022:
    if wonderDate(year, month, day):
        c += 1
    day += 1
    if year in [2004, 2008, 2012, 2016, 2020] and month == 2 and day > 29:
        day = 1
        month += 1
    elif month == 2 and day > 28:
        day = 1
        month += 1
    elif month in [1, 3, 5, 7, 8, 10, 12] and day > 31:
        day = 1
        month += 1
    elif month in [4, 6, 9, 11] and day > 30:
        day = 1
        month += 1
    if month > 12:
        month = 1
        year += 1
print(c)

也可以合理的利用python的datetime库进行一个简单的求解,说白了,本题只要你掌握了合适的API函数,基本就没啥坑点。

import datetime
import math


start = datetime.datetime(year=2001, month=1, day=1)
end = datetime.datetime(year=2021, month=12, day=31)
res = 0
for i in range(1, (end - start).days + 1):
    cur = start + datetime.timedelta(days=i)
    s = str(cur.year) + str(cur.month) + str(cur.day)
    n = sum(list(map(int, s)))
    if pow(int(math.sqrt(n)), 2) == n:
        res += 1
print(res)

【参考答案】

977

试题 D: 最小权值

本题总分:10 分

【问题描述】

对于一棵有根二叉树 T ,小蓝定义这棵树中结点的权值 W ( T ) 如下:

空子树的权值为 0 。

如果一个结点 v 有左子树 L 右子树 R,分别有 C ( L ) 和 C ( R ) 个结点,则
W ( v ) = 1 + 2 W ( L ) + 3 W ( R ) + ( C ( L ) ) 2 C ( R ) 。 W ( v ) = 1 + 2 W ( L ) + 3 W ( R ) + ( C ( L ) )^2 C ( R ) 。 W(v)=1+2W(L)+3W(R)+(C(L))2C(R)
树的权值定义为树的根结点的权值。

小蓝想知道,对于一棵有 2021个结点的二叉树,树的权值最小可能是多 少?

【思路分析】

这道题实际上是一道典型的动态规划dp的题目,dp[i]代表有i个节点的树的最小权值

对于有i个节点的树而言,这棵树的权值取决于根节点的左右子树的分布,我们能够枚举的只是左右子树的节点个数分布,无法直接枚举左右子树形态分布,再看一下题目中所给的权值计算方法可以得到一个结论,树的权值是随着左右子树的权值变小而变小的,也就是说在其他条件不变的情况下(这里的其他条件指的是另一棵子树的形态不变以及节点个数不变),改变某一棵子树的形态使其权值变小则会使整棵树的权值变小,由于左右子树的形态是相互独立的,也就是说在左右子树节点个数一定的情况下我们只需要使得左右子树的权值分别达到最小即可,而这正是我们状态表示中所涵盖的信息,因此就有了状态转移的方程:
d p [ i ] = m i n ( d p [ i ] , 1 + 2 ∗ d p [ j ] + 3 ∗ d p [ i − j − 1 ] + j ∗ j ∗ ( i − j − 1 ) ) dp[i] = min(dp[i],1+2*dp[j]+3*dp[i-j-1]+j*j*(i-j-1)) dp[i]=min(dp[i],1+2dp[j]+3dp[ij1]+jj(ij1))
j是当前根节点左子树的节点个数,而i是当前子树中所有节点的个数,所以右子树的节点个数就是i-j-1(1是根节点),f[j]和f[i-j-1]分别表示在左右子树节点个数一定的情况下的最小权值

由于求的是最小值,所以一开始不要忘记把所有的f数组初始化为正无穷大,把dp[0]初始化为0.

代码code

dp = [float('inf')]*2022
dp[0] = 0

for i in range(1,2022):
    for j in range(i): # 枚举左子树的节点数
        dp[i] = min(dp[i],1+2*dp[j]+3*dp[i-j-1]+j*j*(i-j-1)) # 动态转移方程

print(dp[2021]) # 2653631372

【参考答案】

2653631372

试题 E: 大写

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分

【问题描述】

给定一个只包含大写字母和小写字母的字符串,请将其中所有的小写字母 转换成大写字母后将字符串输出。

【输入格式】

输入一行包含一个字符串。

【输出格式】

输出转换成大写后的字符串。

【样例输入 1】

LanQiao

【样例输出 1】

LANQIAO

【思路分析】

这道题没什么好说的,签到题

代码code

print(input().upper())
创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于2021软件类第十二届蓝桥杯国赛真题 Python组 A-E题解的主要内容,如果未能解决你的问题,请参考以下文章

2021第十二届蓝桥杯国赛C/C++大学B组题解

2021第十二届蓝桥杯国赛C/C++大学B组题解

2021第十二届蓝桥杯国赛C/C++大学B组题解

第十二届蓝桥杯国赛B组 做题记录(python)

第十二届蓝桥杯国赛总结

第十二届蓝桥杯国赛B组 做题记录(python)