第十六届蓝桥杯模拟赛(第一期)-Python

本次模拟赛我认为涉及到的知识点:

  • 分解质因数

  • Python的datetime库

  • 位运算

  • 简单dp

  • 1、填空题

    【问题描述】

    如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。

    请问 2024 有多少个质因数。

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    (1)思路:分解质因数,这里的代码是暴力最笨写出来的,如果是编程题请移步下面链接。

  • 分解质因数的原理讲解,超详细,点这里->质因子分解

  • 分解质因数代码与详细推理讲解->分解质因数

  • (2)代码:

    res=0
    for n in range(2,2025):
        flag = 1
        if 2024%n==0:
            for x in range(2,n):
                if n%x==0:#说明除了1和它本身外还有约数,则不是质数
                    flag=0
                    break
            if flag==1:
                res+=1
    print(res)

    (3)答案:3


    2、填空题

    【问题描述】

    对于一个整数 n ,我们定义一次开根变换会将 n 变为开根号后的整数部分。即变为平方和不超过 n 的数中的最大数。

    例如,20 经过开根变换将变为 4 ,如果再经过一次开根变换将变为 2 ,如果再经过一次开根变换将变为 1 。

    请问,2024经过多少次开根变换后会变为 1 ?

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    (1)思路:暴力

    (2)代码:

    import math
    x=int(math.sqrt(2024))
    res=1
    while x!=1:
        x=int(math.sqrt(x))
        res+=1
    print(res)

    (3)答案:4


    3、填空题

    【问题描述】

    小蓝有很多 1x1x1 的小立方体,他可以使用多个立方体拼成更大的立方体。

    例如,小蓝可以使用 8 个小立方体拼成一个大立方体,每边都是 2 个。

    又如,小蓝可以使用 27 个小立方体拼成一个大立方体,每边都是 3 个。

    现在,小蓝有 2024 个小立方体,他想再购买一些小立方体,用于拼一个超大的立方体,要求所有的小立方体都用上,拼成的大立方体每边长度都相等。

    请问,小蓝最少需要购买多少个小立方体?

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    (1)思路:就是求谁的三次方刚好大于等于2024

              #12*12*12=1728
              #13*13*13=2197
              #2197-2024=173

             蓝桥杯考场可以用计算机哦!

    (2)代码:

             无代码

    (3)答案:173


    4、填空题

    【问题描述】

    如果一个日期的日期以 1 结尾(1日、11日、21日、31日)且为星期一,则称这个日期为一好日期。

    请问从 1901 年 1 月 1 日至 2024 年 12 月 31 日总共有多少个一好日期。

    提示:1901 年 1 月 1 日是星期二。

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    (1)思路:枚举日期

    (2)代码:

    from datetime import datetime, timedelta
    
    # 起始日期和结束日期
    start = datetime(1901, 1, 1)
    end = datetime(2024, 12, 31)
    
    # 统计一好日期
    res = 0
    
    # 从开始日期到结束日期遍历
    t = start
    while t <= end:
        # 只检查以1、11、21、31日结尾的日期
        if t.day % 10 == 1:
            if t.weekday() == 0:  # 0表示星期一
                res += 1
        t += timedelta(days=1)
    
    print(res)
    

    (3)答案:762


    5、填空题

    【问题描述】

    两个数按位异或是指将这两个数转换成二进制后,最低位与最低位异或作为结果的最低位,次低位与次低位异或作为结果的次低位,以此类推。

    例如,3 与 5 按位异或值为 6 。

    小蓝有以下 30 个整数:

    9226, 4690, 4873, 1285, 4624, 1596, 6982, 590, 8806, 121, 8399, 8526, 5426, 64, 9655, 7705, 3929, 3588, 7397, 8020, 1311, 5676, 3469, 2325, 1226, 8203, 9524, 3648, 5278, 8647.

    小蓝想找一个整数 V ,使得 V 与这 30 个数分别异或后,得到的 30 个数的平方和最小。请问平方和最小是多少?

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    (1)思路:

  • v肯定不超过这30个整数的最大数

  • 暴力即可

  • 异或运算

  • (2)代码:

    numbers = [
        9226, 4690, 4873, 1285, 4624, 1596, 6982, 590,
        8806, 121, 8399, 8526, 5426, 64, 9655, 7705,
        3929, 3588, 7397, 8020, 1311, 5676, 3469, 2325,
        1226, 8203, 9524, 3648, 5278, 8647
    ]
    
    smin=float('inf')#初始化和为无穷大
    best_v=0
    for v in range(max(numbers)+1):
        s=sum((num ^ v) ** 2 for num in numbers)#异或运算‘^’
        if s<smin:
            smin=s
            best_v=v
    
    
    print("最小平方和:", smin)
    print("最佳V值:", best_v)#这个不用输出

    (3)答案:1070293541


    6、编程题

    【问题描述】

    小蓝在一个停车场停车。

    停车场的收费规则为:每 15 分钟收费 2 元,不满 15 分钟的不收费。

    小蓝总共停车 n 分钟,请问收费总额是多少?

    【输入格式】

    输入一行包含一个整数 n ,表示小蓝停车的时长。

    【输出格式】

    输出一行包含一个整数,表示停车费用。

    【样例输入】

    150

    【样例输出】

    20

    【样例输入】

    2024

    【样例输出】

    268

    【评测用例规模与约定】

    对于所有评测用例,1 <= n <= 10000。

    (1)思路:

  • 整除15再乘2就好了

  • (2)代码:

    n=int(input())
    print(n//15*2)

    7、编程题

    【问题描述】

    小蓝有一个整数 n ,每次操作,可以将这个整数的每个非零数位减少 1 。

    请问经过多少次操作,这个数会变为 0 。

    例如,整数 2024 经过一次操作变为 1013,再经过一次操作变为 2 (即0002),再经过两次操作变为 0 ,总共经过 4 次变换变为 0 。

    【输入格式】

    输入一行包含一个整数 n 。

    【输出格式】

    输出一行,包含一个整数,表示答案。

    【样例输入】

    2024

    【样例输出】

    4

    【评测用例规模与约定】

    对于 50% 评测用例,1 <= n < 10000。

    对于所有评测用例,1 <= n < 1000000000。

    (1)思路:

  • 答案就是最大的那个位的数

  • (2)代码:

    n=int(input())
    kmax=0
    while n!=0:
        k=n%10
        kmax=max(kmax,k)
        n=n//10
    print(kmax)

     8、编程题

    【问题描述】

    小蓝有一个减法式子,形如 a-b,其中 a 和 b 都是非负整数(不保证结果非负)。

    请编程处理这个式子,输出运算结果。

    【输入格式】

    输入一行包含一个减法表达式,式子中仅含数字字符和一个减号。

    【输出格式】

    输出一行包含一个整数,表示运算结果。

    【样例输入】

    2024-1949

    【样例输出】

    75

    【样例输入】

    20-24

    【样例输出】

    -4

    【评测用例规模与约定】

    对于 50% 的评测用例,减法中的两个数都是不超过 10000 的非负整数。

    对于所有评测用例,减法中的两个数都是不超过 1000000000 的非负整数。

    (1)思路:

  • 就很水的题

  • (2)代码:

    a,b=map(int,input().split('-'))
    print(a-b)

    9、编程题

    【问题描述】

    小蓝有一个长度为 n 的整数数列 a[1], a[2], …, a[n] 。

    对于一个给点的整数 k ,小蓝想找到相邻间隔为 1 的 k 个数 a[p], a[p+2], a[p+4], …, a[p+2k-2],使得他们的和最大。其中 1 <= p <= n-2k+2。

    给定数列和 k ,请问给出最大的和。

    【输入格式】

    输入的第一行包含一个整数 n 。

    第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。

    第三行包含一个整数 k 。

    【输出格式】

    输出一行,包含一个整数,表示答案。

    【样例输入】

    10
    2 1 4 7 4 8 3 6 4 7
    2

    【样例输出】

    15

    【样例说明】

    取 p=4,a[4]+a[6]=7+8=15 最大。

    【评测用例规模与约定】

    对于 30% 的评测用例,1 <= k <= n <= 100 , 1 <= a[i] <= 10000 。

    对于 60% 的评测用例,1 <= k <= n <= 3000 , 1 <= a[i] <= 10000 。

    对于所有评测用例,1 <= k <= n <= 100000 , 1 <= a[i] <= 1000000 。

    (1)思路:

  • 首先求出从数组下标1开始,往后k个奇数下标位置的和与偶数下标位置的和。

  • 接着以长度为k个数,向后滑动,每移动一个,让和减去最前面的数,加上最后面的新进来的数。

  • (2)代码:

    #一开始以为要前缀和,发现没必要,因为只有一组输入
    n=int(input())
    a=list(map(int,input().split(' ')))
    k=int(input())
    a=[0]+a     #让下标从1开始,方便理解
    ji_sum=0#奇数下标的和
    ou_sum=0#偶数下标的和
    for p in range(1,2*k,2):
        ji_sum+=a[p]
        ou_sum+=a[p+1]
    sum1_max=ji_sum
    sum2_max=ou_sum
    for p in range(3,n-2*k+2+1):
        if p%2==1:#奇数下标
            ji_sum-=a[p-2]
            ji_sum+=a[p+2*k-2]
            sum1_max=max(sum1_max,ji_sum)
        else:#偶数下标
            ou_sum-=a[p-2]
            ou_sum+=a[p+2*k-2]
            sum2_max=max(ou_sum,sum2_max)
    print(max(sum1_max,sum2_max))

    10、编程题

    【问题描述】

    小蓝有一个长度为 n 的整数序列 a[1], a[2], …, a[n] 。

    他希望从中找出一个最长的子序列,形成一个勾的形状(√)。

    即找到 1 <= p[1] < p[2] < … < p[k] <= n,满足 a[p[1]] > a[p[2]] > a[p[3]] > … > a[p[x]] < a[p[x+1]] < … < a[p[k]] 。其中 k 是子序列的长度,x 是勾中最小的位置。目标是使得 k 最大。

    请找出最大的勾的长度。

    【输入格式】

    输入的第一行包含一个整数 n 。

    第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。

    【输出格式】

    输出一行,包含一个整数,表示答案。

    【样例输入】

    10
    2 1 4 7 4 8 3 6 4 7

    【样例输出】

    5

    【样例说明】

    当 p = (4,5,7,9,10) 时,a[4] , a[5] , a[7] , a[9] , a[10] 可形成一个长度为 5 的勾:7,4,3,6,7。

    【评测用例规模与约定】

    对于 30% 的评测用例,1 <= n <= 20 , 1 <= a[i] <= 100 。

    对于 60% 的评测用例,1 <= n <= 100 , 1 <= a[i] <= 1000 。

    对于所有评测用例,1 <= n <= 1000 , 1 <= a[i] <= 10000 。

    (1)思路:

  • 简单动态规划

  • 使用两个数组 decreasing 和 increasing。decreasing[i] 表示以 a[i] 结尾的最长严格递减子序列的长度。increasing[i] 表示以 a[i] 开头的最长严格递增子序列的长度。

  • 遍历每个元素 i,并对比它之前的所有元素 j。如果 a[j] > a[i],则更新 decreasing[i] 为 decreasing[j] + 1,表示以 j 结尾的子序列可以延续到 i。

  • 反向遍历每个元素 i,对比之后的所有元素 j。如果 a[j] > a[i],则更新 increasing[i] 为 increasing[j] + 1,表示以 j 结尾的子序列可以从 i 开始。

  • 遍历每个元素 i,检查其对应的递减和递增子序列长度,如果两者都大于 1,则可以组成一个“勾”,并更新最大长度 max_length。

  • (2)代码:

    n = int(input())
    a = list(map(int, input().split()))
    if n < 3:
        print(0)
    else:
        decreasing = [1] * n
        increasing = [1] * n
    
        # 计算每个位置之前的最长递减子序列
        for i in range(n):
            for j in range(i):
                if a[j] > a[i]:
                    decreasing[i] = max(decreasing[i], decreasing[j] + 1)
    
        # 计算每个位置之后的最长递增子序列
        for i in range(n - 1, -1, -1):
            for j in range(i + 1, n):
                if a[j] > a[i]:
                    increasing[i] = max(increasing[i], increasing[j] + 1)
    
        max_length = 0
        for i in range(n):
            if decreasing[i] > 1 and increasing[i] > 1:
                max_length = max(max_length, decreasing[i] + increasing[i] - 1)
    
        print(max_length)
    
    
    

    如有错误,感谢指正

    作者:喜欢发呆~

    物联沃分享整理
    物联沃-IOTWORD物联网 » 第十六届蓝桥杯模拟赛(第一期)-Python

    发表回复