【考前三天】蓝桥杯Python组元年国赛真题详解

前言

今天做一套蓝桥杯python元年的国赛题目,我数了一下5道选择,可以说是福利之年了,以后都不会出现这种情况了,当时python组别刚出现,估计很多大学和专业连python这门课都没开设,或部分开设,咱们废话少嗦直接开敲,这次不看源码哈。
发现有的同学还不清楚比赛环境,贴一个我们学校机子的供参考哈。
在这里插入图片描述

A:美丽的2

在这里插入图片描述
数数题,上来3分钟签个道

ans=0
for i in range(1,2021):
  if str(i).count('2')>0:
    ans+=1
print(ans)

要比赛了就给大家搜一手官方解释趴
在这里插入图片描述

B:合数个数

在这里插入图片描述
这道题就写个简单check函数判断是不是质数,循环输一下就行。

ans=0
def check(i):
  for j in range(2,i):
    if i%j==0:
      return True
  else:
    return False
for i in range(4,2021):
  if check(i):
    ans+=1
print(ans)

C:阶乘约数

在这里插入图片描述
这题我写了一个跑的时间有点长,上网学习了一个大家看下。
总之没第一反应想的那么简单,它要求的是正约数的个数,那它的因子进行排列组合的乘积当然也是它的正约数,质数也可以是约数,而且质数也可以是它的因子组成的,如果用每个因子一个个去除累加次数时间太久,还是通过分解的方式好用,而且约数进行相互间的组合数,就是它们的乘积和

import os
import sys
# 计算100的阶乘有多少因数
n = 100 # 阶乘的参数
p = [2] # 质数列表,初始化为[2]
# 找出100以内的所有质数,存入p
for i in range(3, n + 1):
    j = 2
    while j < i:
        if i % j == 0: # 如果i能被j整除,说明i不是质数
            break
        j += 1
    else: # 如果i不能被任何小于i的数整除,说明i是质数
        p.append(i)
# print(p) # 输出p,查看质数列表

m = {
    
    } # 质因数字典,用来记录每个质因数的个数
for i in p:
    m[i] = 1 # 初始化为1,代表不选这个质因数的可能

# 遍历从2到100的每个数,对每个数进行质因数分解,并更新m中对应的质因数的个数
for i in range(2, n + 1):
    x = i # x为当前要分解的数
    for j in p: # 遍历质数列表
        if j > x: # 如果j大于x,说明x已经分解完毕,跳出循环
            break
        while x % j == 0: # 如果x能被j整除,说明j是x的一个质因数
            x //= j # 将x除以j,并更新x的值
            m[j] += 1 # 将m中j对应的值加一

s = 1 # 约数个数,初始化为1
# 将m中所有的值相乘,得到约数个数
for i in m.values():
    s *= i

print(s) # 输出约数个数
# 请在此输入您的代码

D:本质上升序列

在这里插入图片描述
这题我搜了半天,一开始我以为是数每个字母出现的次数,后来发现递增序列是每个字母只出现一次,所以我们只要记住每个第一次出现产生的个数,它后面重复出现也没作用。我们从前往后数,初始化为1。

x = "tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl"
dp = [1] * 200						#初始化
for i in range(200):				
    for j in range(i):				#当前字母与它前面的字母进行比较
        if x[i] > x[j]:				#现在出现的字典序大于之前,可以产生新的子序列
            dp[i] += dp[j]
        elif x[j] == x[i]:			#之前已经出现了,把前者产生的子序列数量减掉
            dp[i] -= dp[j]
print(sum(dp))						#sum

总的来说这题还是挺复杂的,没那么好想,因为这个字母之前出现过,新增一个对前面没有任何影响,所以把它减掉一个差值,后面求和就抵消掉了

E:玩具蛇

在这里插入图片描述
这题考查深度递归dfs,通过循环将表中每个位置都初始化一次,然后四个方向判断是否超界以及是否有站位。

m=[[0]*4 for i in range(4)]
res=0
def dfs(x,y,cnt):
    global res					#result
    if cnt==16:					#16个位置都走了就结束
        res+=1
        return
    for i,j in [(1,0),(0,-1),(0,1),(-1,0)]:#四个方向
        a,b=x+i,y+j
        if 0<=a<4 and 0<=b<4 and m[a][b]==0:#判断是否可以走
            m[a][b]=1						#站位走下一步
            dfs(a,b,cnt+1)
            m[a][b]=0						#回退到之前
    m[x][y]=0					#回退
    return res
for i in range(4):
    for j in range(4):
        m[i][j]=1
        dfs(x,y,1)
print(res)

F:天干地支

在这里插入图片描述
老取余法了,先判断初试那年的天干地支,60年一个周期,2020%10=0,2020%12=4

N=int(input())
a=['jia','yi','bing','ding','wu','ji','geng','xin','ren','gui']
b=['zi','chou','yin','mao','chen','si','wu','wei','shen','you','xu','hai']
C=N-4
print(a[C%10]+b[C%12])

注意!因为要求两者之间无空格,所以不要用逗号链接,用加号连接字符串。

G:重复字符串

在这里插入图片描述
遇到这种分类的,用dict还是很香的

k = int(input())
s = list(input())
step = len(s)//k    		# 判断子字符串长度
ans = 0
for i in range(step):
    num = dict()
    for j in s[i::step]:    # 分别遍历每个子字符串的第i位,统计其出现次数,num存储出现次数
        if j in num:
            num[j] += 1		# 这个字母之前出现过num+1
        else:
            num[j] = 1
    ans += k-max(num.values())  # k减去字符串该位出现次数最多的num(最多就是不用换的)
    num.clear()				# 清除这个位置的记录
print(ans)

看代码有点抽象,我debug了一下,大家看看,对应子串如果都相同,就和k一样大,有一个不同就要改变一个,结果累加。
在这里插入图片描述

H:答疑

在这里插入图片描述
这题我建议大家先拿笔推推,最后结果就是越小的排前面越好

n=int(input())
li=[]
for i in range(n):
    x,y,z=map(int,input().split())
    A=x+y					#解答时间
    B=x+y+z					#总时间
    li.append([A,B])
li=sorted(li,key=lambda x:x[1],reverse=False)		#用总时间排序
t=0
for i in range(n):
    for j in range(i):				#这层循环添加当前学生之前的学生总时间
        t+=li[j][1]
    t+=li[i][0]						#当前学生的答疑时间
print(t)					#妙!

I:补给

在这里插入图片描述

J:蓝跳跳

在这里插入图片描述

结语

最后两个妹写出来,但是把前八个做通做懂也足够了,记得考前三天把模板整理一下,每天敲敲,找点真题带进去试试,最后祝大家心想事成

猜你喜欢

转载自blog.csdn.net/weixin_53415043/article/details/129955878