蓝桥杯2022 A组 python

蓝桥杯2022 A组 python

A组相对于B组就五道题不一样

第一题:裁纸刀

在这里插入图片描述

就先把四个边剪一下,然后先行后列,蛮简单的

# 20行 横着19刀,竖着21*20
print(19+21*20+4)

第三题:质因数个数

在这里插入图片描述

这题我感觉就是跟一个约数个数的模板一样的,改一点点就好了,也没啥好说的,看代码就行

# 任何一个正整数,都可以拆成质因数的乘积,最多只有一个质因数大于根号N

if __name__ == '__main__':
    n = int(input())
    res = 0
    for i in range(2,n+1):  #寻找他的质因数
        if i > n/i: break # i就循环到根号N  
        if n % i == 0:  # 找到的一定是质数,因为约数在之前一定会被前面的质数给消掉
            res += 1
        while n % i == 0: 
            n = n // i
    if n > 1: res += 1
    print(res)

第四题:矩形拼接

在这里插入图片描述

找到规律就很好做了

四边形:三个都有一条长度相同的边、两个有长度相同的边,且另外两条长度边之和等于第三个矩形的一条边

六边形:两个有长度相同的边、两个矩形的各自一条边之和等于第三个矩形的一条边

八边形: 其他

根据以上规律去写,看得多其实有很多重复的。。认真看一下就行

# 四边形:三个都有一条长度相同的边、两个有长度相同的边,且另外两条长度边之和等于第三个矩形的一条边
# 六边形:两个有长度相同的边、两个矩形的各自一条边之和等于第三个矩形的一条边
# 八边形: 其他

def find(A1,A2,A3):
    for i in A1:
        if A2.count(i) >= 1 and A3.count(i) >= 1: return 4
    
    for i in range(2):
        if A2.count(A1[i]) >= 1 and A3.count(A1[i]) == 0:  # 找到A1 和 A2 有相同长度的边
            for j in range(2):
                if A2[j] == A1[i]:
                    for k in range(2):
                        if A1[i ^ 1] + A2[j ^ 1] == A3[k]: return 4
    for i in range(2):
        if A2.count(A1[i]) == 0 and A3.count(A1[i]) >= 0:  # 找到A1 和 A3 有相同长度的边
            for j in range(2):
                if A3[j] == A1[i]:
                    for k in range(2):
                        if A1[i ^ 1] + A3[j ^ 1] == A2[k]: return 4
    
    for j in range(2):
        if A3.count(A2[j]) >= 1 and A1.count(A2[j]) == 0:
            for k in range(2):
                if A2[j] == A3[k]:
                    for i in range(2):
                        if A2[j ^ 1] + A3[k ^ 1] == A1[i] : return 4
## *******************************和上面基本一样,但return 6 不能在return 4 前面,所以我上面把return 6 删了,又复制了一份*********************************************** ##
    for i in range(2):
        if A2.count(A1[i]) >= 1 and A3.count(A1[i]) == 0:  # 找到A1 和 A2 有相同长度的边
            for j in range(2):
                if A2[j] == A1[i]:
                    for k in range(2):
                        if A1[i ^ 1] + A2[j ^ 1] == A3[k]: return 4
                    else : return 6
    for i in range(2):
        if A2.count(A1[i]) == 0 and A3.count(A1[i]) >= 0:  # 找到A1 和 A3 有相同长度的边
            for j in range(2):
                if A3[j] == A1[i]:
                    for k in range(2):
                        if A1[i ^ 1] + A3[j ^ 1] == A2[k]: return 4
                    else : return 6
    
    for j in range(2):
        if A3.count(A2[j]) >= 1 and A1.count(A2[j]) == 0:
            for k in range(2):
                if A2[j] == A3[k]:
                    for i in range(2):
                        if A2[j ^ 1] + A3[k ^ 1] == A1[i] : return 4
                    else: return 6
    for i in A1:
        for j in A2:
            for k in A3:
                if i + j == k or i + k == j or j + k == i: return 6
    return 8


if __name__ == '__main__':
    n = int(input())
    for _ in range(n):
        edge = [int(x) for x in input().split()]
        A1 = edge[0:2]
        A2 = edge[2:4]
        A3 = edge[4:6]
        print(find(A1,A2,A3))

第六题:重新排序

在这里插入图片描述

最开始的sum不用我说,我们需要的是怎么求后面的sum? 就是把每个位置的被求的次序都收集起来,某个位置被求的次数最多,我们就把最大值放到他这个位置上。那么我们只需要求完次序,然后分别对次序数组和原来的A数组排序,分别相乘就好了

代码1

if __name__ == '__main__':
    n = int(input())
    A = [int(x) for x in input().split()]
    s = [0]*(n+1)
    m = int(input())
    C = [0]*(n+1) # 用来存储每个数被查询了几次
    sum0 = 0
    for i in range(m):
        a,b = map(int,input().split())
        for i in range(a-1,b):  # 数组中的下标要-1
            sum0 += A[i]
            C[i] += 1
    A.sort()
    C.sort()
    sum1 = 0
    for i in range(n):
        sum1 += C[i]*A[i]
    print(sum1 - sum0)

这个代码看起来很简单,但是你会发现,for i in range(a-1,b)这个最坏要循环n次,那整体时间复杂度都是O(mn)太大了,我们要想办法如何优化这一块

那么求和我们就想到了前缀和,这样我们就不用遍历所有的去求和了,求次数呢我们也可以用类似的想法,看最终优化后的代码 — 在ACWING上全通过了

if __name__ == '__main__':
    n = int(input())
    A = [int(x) for x in input().split()]
    s = [0]*(n+1)
    for i in range(1,n+1):
        s[i] = s[i-1] + A[i-1]
    m = int(input())
    C = [0]*(n+1) # 用来存储每个数被查询了几次
    sum0 = 0
    for i in range(m):
        a,b = map(int,input().split())
        # for i in range(a-1,b):  # 数组中的下标要-1
        #     sum0 += A[i]
        #     C[i] += 1
        sum0 += (s[b] - s[a-1])
        C[a-1] += 1
        C[b] -=1
    for i in range(1,n):
        C[i] += C[i-1]
    C = C[:n]
    A.sort()
    C.sort()
    sum1 = 0
    for i in range(n):
        sum1 += C[i]*A[i]
    print(sum1 - sum0)

第十题:数的拆分

在这里插入图片描述

这题我感觉还是那个约数个数的模板。。就变一点而已,可能时间复杂度上要考虑? 我这边没有找到题测试,但测试的数据是没问题,蛮简单的我们就直接看代码把

import math
if __name__ == '__main__':
    T = int(input())
    for _ in range(T):
        n = int(input())
        res = [0] * (int(math.sqrt(n))+1)
        for i in range(2,n):
            if i > n/i: break
            while n % i == 0:
                res[i] += 1
                n = n//i
        if n > 1: 
            print('no')
            continue
        if 1 not in res:print('yes')

猜你喜欢

转载自blog.csdn.net/abc1234564546/article/details/128815484