第十五届蓝桥杯大赛软件赛省赛Python大学C组

免费无广纯净版微信小程序测mbti很有趣,不需要任何授权,也不需要登录,直接就是测,几分钟了解自己的人格mbti,快来试试吧。

可以微信直接搜索小程序名“一秒MBTI”

拼正方形

问题描述

分析

   蓝桥杯填空题很多时候都是极端情况蒙一下,对了就赚了,不对也没关系,毕竟分值不高,而且有时候很难想到正常的解法。

蒙题思路:

全部使用2x2的方块一定比全部使用1x1的方块总边长最大,因此我们假设全部使用2x2的方块,设m个方块可以组成最大方块,则m=i*i(因为只有 平方个数量的小正方形才能组成一个大正方形)m<= 7385137888721,求出最大的m(此时res*res=m),大正方形面积为:4m,边长为2*m^0.5,即2*res.

AC代码

def main():
    res = 0
    i = 1
    while True:
        if i * i <= 7385137888721:
            res = i
            i += 1
        else:
            break
    print(2*res)

if __name__ == "__main__":
    main()

劲舞团

问题描述

分析

连击的定义

  1. K 连击要求连续 K 次敲击都是正确的(correct_char == input_char)。
  2. 任意连续两次正确敲击之间的时间间隔必须 ≤ 1 秒(1000 毫秒)。
  3. 如果某次敲击错误或时间间隔超过 1 秒,连击中断,需要重新计数。

关键点

  1. 需要记录所有敲击的时间戳和正确性。
  2. 判断连击时,不仅要检查当前敲击是否正确,还要与前一次正确敲击的时间间隔是否满足条件。
  3. 错误敲击会打断连击,但不会影响后续连击的计算。

算法思路

  1. 读取所有敲击记录,存储时间戳和是否正确的标记。
  2. 遍历记录,维护当前连击数(current_combo)和最大连击数(max_combo)。
  3. 对于每次敲击:

如果正确:

  • 如果是第一次正确敲击,current_combo = 1。
  • 如果与前一次敲击时间间隔 ≤ 1000 毫秒,current_combo += 1。否则,重置 current_combo = 1。
  • 更新 max_combo。

如果错误:重置 current_combo = 0。

最后返回 max_combo。

AC代码

def find_longest_combo():
    # 存储所有敲击记录(包括正确和错误的)
    all_hits = []
    
    # 读取输入数据
    while True:
        try:
            line = input().strip()
            if not line:  # 跳过空行
                continue
            correct_char, input_char, timestamp = line.split()
            timestamp = int(timestamp)
            
            # 记录所有敲击,并标记是否正确
            is_correct = (correct_char == input_char)
            all_hits.append((timestamp, is_correct))
        except EOFError:
            break
    
    # 计算最长连击
    max_combo = 0
    current_combo = 0
    
    for i in range(len(all_hits)):
        timestamp, is_correct = all_hits[i]
        
        if is_correct:
            # 如果是第一个正确敲击或与前一个正确敲击连续(中间没有其他敲击且时间间隔不超过1秒)
            if current_combo == 0:
                current_combo = 1
            elif timestamp - all_hits[i-1][0] <= 1000:
                current_combo += 1
            else:
                current_combo = 1
                
            max_combo = max(max_combo, current_combo)
        else:
            # 错误敲击,重置连击
            current_combo = 0
    
    return max_combo

# 计算并输出结果
result = find_longest_combo()
print(result)

数字诗意

问题描述

输入输出与样例

分析

经过分析 1~20的数,只有2的k次方才不满足,而这样的数的二进制表示1的个数是奇数,从而找到规律,结果就是p(p是二进制表示1的个数是奇数的数字的数量)

AC代码

# 计算一个数的二进制表示中 1 的个数
def count_ones(n):
    count = 0
    while n:
        count += n & 1  # 检查最低位是否为 1
        n >>= 1        # 右移一位
    return count

# 输入
n = int(input())
numbers = list(map(int, input().split()))

# 计算 p,即二进制表示中 1 的个数为奇数的数的数量
p = 0
for num in numbers:
    if count_ones(num) % 2 == 1:  # 1 的个数是奇数
        p += 1

# 输出结果 p
print(p)

封闭图形个数

问题描述

输入输出与样例

 分析

这道题目描述了蓝桥王国的一种特殊数字排序规则,主要基于两个标准:

  1. 首要标准:数字中"封闭图形"的个数,封闭图形较少的数字较小
  2. 次要标准:如果封闭图形个数相同,则按照数值大小排序
  • 时间复杂度: O(n log n * m),其中n是数字的数量,m是最大数字的位数。排序需要O(n log n),而为每个数计算封闭图形需要O(m)
  • 空间复杂度: O(n),用于存储排序结果

AC代码

def count_closed_shapes(num):
    # 字典映射每个数字到它包含的封闭图形数量
    shapes = {'0': 1, '1': 0, '2': 0, '3': 0, '4': 1, 
              '5': 0, '6': 1, '7': 0, '8': 2, '9': 1}
    
    # 将数字转换为字符串并累加封闭图形的数量
    total_shapes = sum(shapes[digit] for digit in str(num))
    return total_shapes

def main():
    # 读取输入
    n = int(input())
    numbers = list(map(int, input().split()))
    
    # 按封闭图形数量(首要条件)和数值大小(次要条件)排序
    sorted_numbers = sorted(numbers, key=lambda x: (count_closed_shapes(x), x))
    
    # 输出结果
    print(" ".join(map(str, sorted_numbers)))

if __name__ == "__main__":
    main()

回文数组

问题描述

输入输出与样例

 

 

分析

思路:贪心

题目要求将一个随机数组变成一串回文数,可执行的操作如下:

  • 相邻两个数同时加 1
  • 单个数加 1 或减 1

由于一个数加 1 得到回文数和一个数减 1 得到回文数效果一样,我们可以不考虑减 1 的情况。

很显然,相邻两个数同时加 1 要比单个数加 1 或减 1 的步数少,于是我们优先将相邻两个数同时加 1。

实现

我们用数组 b 来存放 ai 需要变化的次数,然后计算相邻两个数可以同时加 1 的次数,最后加上单个数加 1 的次数。

AC代码

import sys

input = lambda: sys.stdin.readline().strip()

# 读取输入
n = int(input())
a = list(map(int, input().split()))

# 计算差值数组 d,d[i] 表示 a[i] 与 a[n-1-i] 的差值
d = []
for i in range(n // 2):
    d.append(a[i] - a[n - i - 1])

# 更新 n 为差值数组的长度
n = len(d)
res = 0  # 记录总操作次数

# 贪心计算最小操作次数
for i in range(n):
    res += abs(d[i])  # 每次至少需要 abs(d[i]) 次单次操作
    if i != n - 1:  # 如果不是最后一个元素
        if d[i] > 0 and d[i + 1] > 0:  # 两个正数,说明左边需要减,右边需要减
            d[i + 1] -= min(d[i], d[i + 1])  # 使用相邻操作,减少 d[i+1]
        elif d[i] < 0 and d[i + 1] < 0:  # 两个负数,说明左边需要加,右边需要加
            d[i + 1] -= max(d[i], d[i + 1])  # 使用相邻操作,减少 d[i+1]

# 输出结果
print(res)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoveYa!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值