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

前言

抱着试一试的心态看看今年的蓝桥杯模拟赛试题会不会像往年一样水,结果果然不出我所料,还是那么

 毕竟模拟赛嘛,如果出难了,蓝桥杯还怎么吸引广大大学生们参加~

但是最让我不解的是!为什么题目是去年的原题

原题?是原题!是原题!蓝桥杯官方连出道新题都这么难了吗!?

 不说了,其实还是有两道新题的对吧~😒

 总共12道题,时间4个小时

第一题

解题思路

考察:思维

2022的十六进制表示是7E6,因为要求十六进制下的最小值,所以答案也是3位,只能是AAA了,而AAA的十进制表示是2730,所以这道题的答案就是2730。

第二题

 解题思路

考察:找规律

这里给出规律:对于一个长度为n的列名C,它的列数为:(C0到Cn-1分别是最低位到最高位)

(C_{n-1}-'A'+1)\times26^{n-1}+(C_{n-2}-'A'+1)\times26^{n-2}+...+(C_{0}-'A'+1)\times26^{0}

 所以第2022的列名就是

2022/26/26\%26-1+'A'~~---~~'B'\\\\2022/26\%26-1+'A'~~---~~'Y'\\\\2022\%26-1+'A'~~---~~'T'

第三题

 解题思路

考察:枚举(日期相关)

这道题直接编程求解即可,枚举1900年1月1日到9999年12月31日的每一天,并判断当天是否满足要求,详解看注释

代码

d = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # d[i]:i月的天数(非闰年)
cnt = 0
for i in range(1900, 10000): # 遍历年
    if i % 4 == 0 and i % 100 != 0 or i % 400 == 0: d[2] = 29 # 闰年
    else: d[2] = 28 # 非闰年
    for j in range(1, 13): # 遍历月
        for k in range(1, d[j] + 1): # 遍历日
            y, m, day = 0, 0, 0
            t = i # 年
            while t:
                y += t % 10
                t //= 10
            t = j # 月
            while t:
                m += t % 10
                t //= 10
            t = k # 日
            while t:
                day += t % 10
                t //= 10
            if y == m + day: # 满足要求
                cnt += 1
print(cnt)

最后答案为70910

第四题

 解题思路

考察:枚举

同上,直接编程求解,详解请看代码

代码

a = [99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77]
cnt = 0
for i in range(29): # 第一层循环
    for j in range(i + 1, 30): # 第二层循环
        if a[i] * a[j] > 2022:
            cnt += 1
print(cnt)

最后答案为189

第五题

 解题思路

考察:搜索

连通块问题,dfs解决(bfs也可),对于遍历过的位置置0,以防重复计算,并用一个mx记录当前最大联通块大小。最后的mx即为答案

代码

mx = 0
g = [list(input()) for i in range(30)]
    
def dfs(x, y):
    g[x][y] = '0' # 取消标记
    cnt = 1
    for nx, ny in [(x - 1, y), (x, y - 1), (x + 1, y), (x, y + 1)]:
        if 0 <= nx < 30 and 0 <= ny < 60 and g[nx][ny] == '1':
            cnt += dfs(nx, ny)
    return cnt

for i in range(30):
    for j in range(60):
        if g[i][j] == '1':
            res = dfs(i, j)
            if res > mx: # 更新最大值
                mx = res
print(mx)

最后输出148

附矩阵:

110010000011111110101001001001101010111011011011101001111110
010000000001010001101100000010010110001111100010101100011110
001011101000100011111111111010000010010101010111001000010100
101100001101011101101011011001000110111111010000000110110000
010101100100010000111000100111100110001110111101010011001011
010011011010011110111101111001001001010111110001101000100011
101001011000110100001101011000000110110110100100110111101011
101111000000101000111001100010110000100110001001000101011001
001110111010001011110000001111100001010101001110011010101110
001010101000110001011111001010111111100110000011011111101010
011111100011001110100101001011110011000101011000100111001011
011010001101011110011011111010111110010100101000110111010110
001110000111100100101110001011101010001100010111110111011011
111100001000001100010110101100111001001111100100110000001101
001110010000000111011110000011000010101000111000000110101101
100100011101011111001101001010011111110010111101000010000111
110010100110101100001101111101010011000110101100000110001010
110101101100001110000100010001001010100010110100100001000011
100100000100001101010101001101000101101000000101111110001010
101101011010101000111110110000110100000010011111111100110010
101111000100000100011000010001011111001010010001010110001010
001010001110101010000100010011101001010101101101010111100101
001111110000101100010111111100000100101010000001011101100001
101011110010000010010110000100001010011111100011011000110010
011110010100011101100101111101000001011100001011010001110011
000101000101000010010010110111000010101111001101100110011100
100011100110011111000110011001111100001110110111001001000111
111011000110001000110111011001011110010010010110101000011111
011110011110110110011011001011010000100100101010110000010011
010011110011100101010101111010001001001111101111101110011101

 第六题

 代码

w = int(input())
n = int(input())
w = w - 1 + n # 0~6分别对应星期一到星期天
print(w % 7 + 1)

一个一个枚举也可以

(真是大水题!)

第七题

 解题思路

考察:模拟

依次对信号塔覆盖的范围进行标记即可,未覆盖的位置置0,覆盖的位置置1,最后总和就是覆盖的范围

代码

W, H, n, R = map(int, input().split())
area = [[0] * (W + 1) for i in range(H + 1)]
for i in range(n):
    x, y = map(int, input().split())
    for i in range(x - R, x + R + 1):
        if 0 <= i <= W:
            for j in range(y - R, y + R + 1):
                if (i - x)**2 + (j - y)**2 > R**2: # 超出了圆的范围
                    continue
                if 0 <= j <= H:
                    area[i][j] = 1
print(sum([sum(i) for i in area]))

第八题

 解题思路

考察:模拟

同上,依次枚举并标记

代码

n, m = map(int, input().split())
t = int(input())
area = [[1] * m for i in range(n)]
while t:
    r1, c1, r2, c2 = map(int, input().split())
    for i in range(r1 - 1, r2):
        for j in range(c1 - 1, c2):
            area[i][j] = 0
    t -= 1
print(sum([sum(i) for i in area]))

第九题

解题思路

考察:记忆化搜索

用dfs实现,用一个矩阵记录每个位置可以滑行的最远距离

代码

res = 1
n, m = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(n)]
ans = [[-1] * m for _ in range(n)] # 记录可以滑行的最远距离

def dfs(i, j):
    global res
    if ans[i][j] != -1: # 已经计算过,直接返回
        return ans[i][j]
    ans[i][j] = 1
    for x, y in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:
        if 0 <= x < n and 0 <= y < m and g[i][j] > g[x][y]:
            ans[i][j] = max(ans[i][j], dfs(x, y) + 1)
    if res < ans[i][j]:
        res = ans[i][j]
    return ans[i][j]

for i in range(n):
    for j in range(m):
        dfs(i, j)
print(res)

 第十题

解题思路

考察:单调队列

就是求滑动窗口最值,这是一道单调队列模板题

代码

from collections import *
n = int(input())
a = list(map(int, input().split()))
k = int(input())
q = deque()
for i in range(k):
    while q and a[q[-1]] >= a[i]: q.pop()
    q.append(i)
for i in range(n):
    while q and i + k < n and a[q[-1]] >= a[i + k]: q.pop() # 去尾
    if i + k < n: q.append(i + k) # 先判断有没有出界在决定加不加到队列
    while q[0] < i - k: q.popleft() # 去头
    print(a[q[0]], end=" ") # 输出一个结果

第十一题

解题思路

考察:模拟

直接模拟就行:对折一次就是长度变为原来的1/2

大水题,真无语

代码

L = int(input())
cnt = 0 # 次数
while L > 1:
    L /= 2
    cnt += 1
print(cnt)

第十二题

 解题思路

考察:字符串,单调队列

首先我们要知道:要保证字典序最小,就要保证最前面的字符最小,所以思路为:

不断地找前m + 1个字符的最小值,删除最小值前面的字符串,并更新m为之后需要删除的字符个数(减去删除的字符数),找最小值的过程可以用单调队列优化,需要记录上次遍历的最后的位置

时间复杂度O(n)

代码

from collections import *
n, m = map(int, input().split())
s = input()
q = deque()
res = "" # 记录找到的最小值字符
pre, lst = 0, 0 # 之前最小值的下一个位置,下一次开始遍历的位置
while m: # m为0了就是不需要再继续删除了
    for j in range(lst, pre + m + 1):
        while q and s[q[-1]] > s[j]: q.pop()
        q.append(j)
    lst = pre + m + 1
    front = q[0]
    res += s[front]
    m -= front - pre
    pre = front + 1
    q.popleft()
print(res + s[pre:]) # 输出结果

以上就是这场模拟赛的全部题解~如果有错误,还请各位大佬批评指正

最后排名出来了,Python组的报名人数比较少。。。

有问题欢迎在评论区留言~

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南宫谨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值