第十二届蓝桥杯大赛软件赛决赛_PA(题解)

昨天在C站看到蓝桥杯python组的决赛题目,一时激发好奇心,试着做了一遍。

题目可在链接中获取:https://pan.baidu.com/s/11D2yx6ysyDFXbheR-o9kNg 
提取码:q46i 

由于不知道蓝桥杯测试接口怎么要求,我就自己写了本地测试的部分,也按照题目要求生成了极限条件下的测试数据。如果上传接口只需稍作调整。

  • 试题A:带宽
#1Byte = 8bit
#1MB/s = 8Mbps = 8Mb/s = 8 * 1024 Kb/s = 8 * 1024 * 1024 b/s
print(200 / 8, 'MB/s')
  • 试题B:纯质数
import time
from itertools import combinations_with_replacement

n = 20210605
start = time.time()
L = ['2', '3', '5', '7']
count = 0

def isPrime(n):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True
#res = []
def find_P(n):
    global count
    for i in range(len(str(n))):
        L1 = list(combinations_with_replacement(L, i + 1))
        #print(L1)
        L2 = []    
        for j in L1:
            if int(''.join(j)) > n:
                return count
            if isPrime(int(''.join(j))):
                L2.append((''.join(j)))
                count += 1
                #res.append(int(''.join(j)))
        L1 = L2[::]

print(find_P(n))
print('用时:', time.time() - start)    
  • 试题C:完全日期
from datetime import date, timedelta

d1 = date(2001,1,1)
d2 = date(2021,12,31)
count = 0
while d1 <= d2:
    n1 = d1.__format__('%Y%m%d')
    sum_n = 0
    for i in n1:
        sum_n += int(i)
    if sum_n ** 0.5 == int(sum_n ** 0.5):
        #print(n1)
        count += 1
    d1 += timedelta(1)

print(count)
  • 试题D:最小权值
#刚发现居然跳了一题
#应该用动态规划加二叉树可以求解
#这部分晚点我再补上,不好意思
  • 试题E:大写
#这题可能我没看懂,否则也太简单了吧
s = input('请输入只包含大小写字母的字符串:')
print(s.upper())
  • 试题F:123
#一开始的方法不够高效,我也贴上来供大家参考。测试数据可以自己生成
#3
#1 1
#1 3
#5 8

T = int(input('请输入T:'))
'''
n = int(input('请输入数据长度的级数范围n:'))    #由于测试数据最大是10**12次,这个方式就不行了
L = []
count = 0
while count <= 10**n:
    for i in range(1, 5):
        for j in range(1, i + 1):
            L.append(j)
            count += 1

for i in range(T):
    l, r = int(input('请输入l:')), int(input('请输入r:'))
    print(sum(L[l - 1: r]))
    '''
'''
def solution(l, r):
    index = -1
    sum_L = 0
    lenth = 0
    while True:        
        L = []        
        for i in range(lenth + 1):
            L.append(i + 1)
            index += 1
            if index == l - 1:
                sum_l = sum_L + sum(L)
                last = L[-1]
                print('last=', last)
                print(sum_l)
            if index == r - 1:
                sum_r = sum_L + sum(L)
                print(sum_r)
                if r == l:
                    res = L[-1]
                else:
                    res = sum_r - sum_l + last                
                return res
        sum_L += sum(L)
        lenth += 1
'''
def solution(l, r):
    index = 0
    sum_L = 0
    sum_lr = 0    
    lenth = 0
    while True:
        lenth += 1
        sum_L += lenth        
        sum_lr += sum_L
        #print('sum_lr=', sum_lr)
        if l > index:
            index += lenth
            #print('l=', l, 'index=', index)
            if l <= index:
                last1 = lenth - (index - l)
                sum_l = sum_lr - sum_L + sum([i for i in range(1, last1 + 1)])
                #print('sum_l=', sum_l)                
                #print('last1=', last1)
                break
    index -= lenth
    sum_lr -= sum_L
    sum_L -= lenth
    lenth -= 1    
    while True:
        lenth += 1        
        sum_L += lenth
        sum_lr += sum_L
        if r > index:
            index += lenth
            if r <= index:
                last2 = lenth - (index - r)
                #print('last2=', last2)
                sum_r = sum_lr - sum_L + sum([i for i in range(1, last2 + 1)])
                #print('sum_r=', sum_r)
                if l == r:
                    res = 1
                else:
                    res = sum_r - sum_l + last1
                return res             
            
        #print('lenth=', lenth, 'index=', index, 'sum_lr=', sum_lr, 'sum_L=', sum_L)


for i in range(T):
    l, r = int(input('请输入l:')), int(input('请输入r:'))
    print(solution(l, r))
  • 试题G:冰山
#用10^9范围内的最大质数998244353求余

n, m, k = 1, 3, 6
V = [1]
M = [[6, 1],
     [2, 2],
     [-1, 1]]

def func(V:list[int], M_i:list[int], k:int):
    V1 = []    
    for i in V:
        i += M_i[0]
        if i <= 6:
            if i > 0:
                V1.append(i)
        else:
            while i > k:
                V1.append(k)
                i -= k
            if i > 0:
                for i in range(i):
                    V1.append(1)        
    V1.append(M_i[1])
    return V1

for i in range(m):
    #print(V, M[i], k)
    V = func(V, M[i], k)
    print(sum(V) % 998244353)
  • 试题H:和与乘积
from random import randint
import time
#n = 4
#A = [1, 3, 2, 2]
n = int(input('请输入n:'))
A = [randint(1, n) for i in range(n)]
start = time.time()
ans = len(A)
'''
#数据大于1000时就会溢出,不合适
for i in range(n - 1):
    sum_a = A[i]
    pro_a = A[i]
    j = i + 1
    while j < n:
        sum_a += A[j]
        pro_a *= A[j]
        if sum_a == pro_a:
            ans += 1
        j += 1
        '''
#利用n个数的和等于乘积时,必定和为2n的特性缩短时间
for i in range(n - 1):
    j = i + 1
    while sum(A[i : j + 1]) <= 2 * n and j < n:
        sum_a = sum(A[i : j + 1])
        #print(sum_a)
        if sum_a == 2 * (j - i + 1):        
            pro_a = 1
            for k in A[i: j + 1]:
                pro_a *= k
            #print(pro_a)
            if sum_a == pro_a:
                ans += 1
        j += 1

print(ans)
print('用时:', time.time() - start)
  • 试题I:二进制问题
#N, K = 7, 2
N, K = 10 ** 18, 50

s = bin(N)[2:]
lenth = len(s)
if K > lenth - K:
    K = lenth - K
ans = lenth
for i in range(1, K):
    lenth -= 1
    if K == 0:
        break
    ans *= lenth
print(ans)
  • 试题J:翻转括号序列
#定义(为1,)为-1
'''
n, m = 7, 5
s = "((())()"
M = [[2, 3],
     [2, 2],
     [1, 3, 5],
     [2, 3],
     [2, 1]]
for i in s:
    if i == "(":
        S.append(1)
    if i == ")":
        S.append(-1)
     '''
#随即生成一组最大长度范围的测试数据
from random import randint
n = 1000000
S = [[1, -1][randint(0, 1)] for i in range(n)]
M = [[2, randint(1, n)]]
import time
start = time.time()

def cvt_S(S:list[int], Li, Ri):
    S1 = S[Li - 1 : Ri]
    S2 = [i * (-1) for i in S1]
    return S[:Li - 1] + S2 + S[Ri:]

def find_S(S:list[int], Li):
    S1 = S[Li -1:]    
    if S1[0] == 1:
        check = 1
    else:
        return 0
    Ri = Li
    #print('S1=', S1)
    count = 0
    for i in range(1, len(S1)):
        count += 1
        #print('Ri=', Ri)
        if S1[i] == 1:
            check += 1
        else:
            check -= 1
        if check == 0:
            Ri += count
            count = 0
            if Ri < len(S):
                if S1[i + 1] == 1:
                    continue
                else:
                    return Ri
            else:
                return Ri            
    if check > 0:
        return 0
    else:
        return Ri
#print('初始S=', S)    
for i in M:
    if i[0] == 1:
        S = cvt_S(S, i[1], i[2])[::]
        #print('转换后S=',S)
    if i[0] == 2:
        #print('当前S=', S) 
        print(find_S(S, i[1]))

print('用时:', time.time() - start)

我是个退休在家自学python的初学者,平时会教教社区小朋友编程和国际象棋。我也是第一次尝试蓝桥杯,估计其中还有不少问题。

这也是我第一次发帖,希望大家多多包涵!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值