第十三届蓝桥杯省赛C组

试题A:排列字母

  • 结果:AAAEEEEHHHIIILLRRRSSTTWWWY

试题B:特殊时间

  • 分析:

题解


  • 最后结果为:

试题C:纸张尺寸

法一、暴力

a,b=1189,841
re=[1189,841]
for i in range(1,10):
    t=a
    a = b
    b = t // 2
    re.append(a)
    re.append(b)
n=str(input())
if n=='A0':
    print(re[0])
    print(re[1])
if n=='A1':
    print(re[2])
    print(re[3])
if n=='A2':
    print(re[4])
    print(re[5])
if n=='A3':
    print(re[6])
    print(re[7])
if n=='A4':
    print(re[8])
    print(re[9])
if n=='A5':
    print(re[10])
    print(re[11])
if n=='A6':
    print(re[12])
    print(re[13])
if n=='A7':
    print(re[14])
    print(re[15])
if n=='A8':
    print(re[16])
    print(re[17])
if n=='A9':
    print(re[18])
    print(re[19])

试题D:数位排序

题解

  • 思路:遍历1到n+1生成数组作为键,对每个值的每一位求和作为值,先对数组的值进行升序排序,,再对数组的键进行升序排序,最后返回m-1位置的数
n=int(input())
m=int(input())
# 创建一个字典,键为数字,值为数字各位数字之和
num_sum = {}
for i in range(1, n+1):
    digit_sum = sum(int(d) for d in str(i))#计算每个数字的各位数字之和
    num_sum[i] = digit_sum#将数字 i 作为键,其各位数字之和作为值存储在字典 num_sum 中
# 对字典进行排序,先按值排序,再按键排序
sorted_nums = sorted(num_sum.items(), key=lambda x: (x[1], x[0]))#首先按值 x[1] 进行升序排序,如果值相同,则按键 x[0] 进行升序排序
# 输出第m-1个数字
print(sorted_nums[m-1][0])
  • 92分

试题E:矩形拼接

  • 见同文件夹其他文章

试题F:GCD

  • 先判断a,b是否存在公倍数,存在输出0,接着a++,b++,k++,再判断ab是否存在公倍数,存在输出k,不存在继续ab++

法一

def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a#最大公约数
k = 0
a, b = map(int, input().split())
while True:
    if gcd(a, b) != 1:  # 如果a和b有公约数,则输出0
        print(0) #k=0,对a,b本身判断如果有公约数直接输出0
        break
    else:#当ab没有公约数
        a += 1 #每次进行加1
        b += 1
        k += 1
        if gcd(a, b) != 1:  # 如果新的a和b有公约数,则输出k
            print(k)
            break
  • 19分,大多数超出时间限制

法二

  • 当a<=b时,根据更相减损术可以知道一个等式:gcd(a,b)=gcd(a,b-a);所以gcd(a+k,b+k)=gcd(a+k,b-a);设c=b-a ,想要使得a+k与c的最大公因子尽可能地大,因为最大最大能到达c ,显然这个式子的最大gcd一定为 c;只需要计算出a 最少需要增加多少可以成为 c 的倍数,这个增量即是答案k。
a, b = map(int, input().split())
if a > b:
    a, b = b, a
c = b - a
g = a // c
if a % c:
    g += 1
print(g * c - a)

试题G:蜂巢

  • 分析

题解

dx = [0, -1, -1, 0, 1, 1]  # 设置方向对应的 x,y 轴变动,例如:方向 0 的时候 x 轴不动,方向 1 的时候 y 轴 -1
dy = [-1, 0, 1, 1, 0, -1]
alist = []  # 存储两点
blist = list(map(int, input().split()))
blist = [blist[0:3], blist[3:]]  # 读入数据,将输入的列表分为两个子列表,每个子列表包含三个元素,即两点的方向和移动步数
for x in range(2):  # 计算两点的坐标
    a, b, c = blist[x]  # 获取当前点的方向和移动步数
    i, j = 0, 0  # 初始化当前点的坐标为 (0, 0)
    i += dx[a] * b  # 根据方向和移动步数更新当前点的 x 坐标
    j += dy[a] * b  # 根据方向和移动步数更新当前点的 y 坐标
    a = (a + 2) % 6  # 改变方向,将当前方向加 2 并取模 6,以获取下一个方向
    i += dx[a] * c  # 根据新的方向和移动步数更新当前点的 x 坐标
    j += dy[a] * c  # 根据新的方向和移动步数更新当前点的 y 坐标
    alist.append([i, j])  # 将计算得到的点的坐标添加到 alist 列表中
tx = alist[1][0] - alist[0][0]  # 计算 x 轴的差值
ty = alist[1][1] - alist[0][1]  # 计算 y 轴的差值
if tx * ty < 0:  # 如果 x 轴的差值和 y 轴的差值异号(一个正数,一个负数)
    tx = abs(tx)  # 将 x 轴的差值取绝对值
    ty = abs(ty)  # 将 y 轴的差值取绝对值
    print(max(tx, ty))  # 输出 x 轴和 y 轴差值的较大值
else:
    print(abs(tx) + abs(ty))  # 输出 x 轴和 y 轴差值的绝对值之和

试题H:重新排序

代码:前缀和/差分

# 定义常量 N
N = 1000005
# 定义数组 a 和 cnt,分别存储原数组的数值和每个数出现的次数
a = [0] * N
cnt = [0] * N
# 定义差分数组 diff,用来求出cnt
diff = [0] * N
# 读入 n 和原数组 a
n = int(input())
a[1:n+1] = map(int, input().split())
# 读入 m
m = int(input())
# 定义 sum1 和 sum2,分别表示原数组和最优数组的总和
sum1, sum2 = 0, 0
# 遍历所有的查询
for _ in range(m):
    # 读入查询的左右端点
    l, r = map(int, input().split())
    # 对差分数组 diff 进行差分
    diff[l] += 1
    diff[r+1] -= 1
# 计算 cnt 数组
for i in range(1, n+1):
    cnt[i] = cnt[i - 1] + diff[i]
# 计算原数组的总和
for i in range(1, n+1):
    sum1 += a[i] * cnt[i]
# 对 a 和 cnt 数组排序(如果a和cnt都递增则结果最大;若a和cnt一个递增一个递减则结果最小)
a[1:n+1] = sorted(a[1:n+1])
cnt[1:n+1] = sorted(cnt[1:n+1])
# 计算最优数组的总和
for i in range(1, n+1):
    sum2 += a[i] * cnt[i]
# 输出答案
print(sum2 - sum1)

试题I:青蛙过河

  • 一只蛙,从起点到终点跳x次,再从终点到起点也是x次,可以理解为:从起点到终点跳2x次;可以进一步转化为:有2x只蛙从起点跳到终点

代码

  • 未理解,下面是参考网上大家的代码
n, x = map(int, input().split())  # 读取输入的 n 和 x
a = list(map(int, input().split()))  # 读取输入的数组 a
s = [0] * (n + 1)  # 创建一个长度为 n+1 的数组 s,用于存储前缀和

for i in range(1, n):
    s[i] = s[i - 1] + a[i]  # 计算数组 a 的前缀和,存储到数组 s 中
def check(m):
    for i in range(1, n - m + 1):
        # 判断是否任意长度为 m 的区间都满足 >= 2x
        if s[i + m - 1] - s[i - 1] < 2 * x:
            return False
    return True
l = 1  # 初始区间长度的最小值
r = n  # 初始区间长度的最大值
while l < r:
    mid = (l + r) // 2  # 计算区间长度的中间值
    if check(mid):
        r = mid  # 如果满足条件,则将右边界更新为 mid
    else:
        l = mid + 1  # 如果不满足条件,则将左边界更新为 mid+1
print(l)  # 输出满足条件的最小区间长度

试题J:因数平方和

见同文件夹其他文章

posted @ 2024-03-18 17:00  Frommoon  阅读(20)  评论(0编辑  收藏  举报