蓝桥杯【第13届省赛】Python B组 98.95分

这篇具有很好参考价值的文章主要介绍了蓝桥杯【第13届省赛】Python B组 98.95分。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

只能说这波有点混,我估计 48.5 分左右 (满分 150)。广东总共 78 个省一,我只排到了第 33 (42.3%)

考前主要在力扣上面练,考试时发现并无卵用,打蓝桥杯还是要以真题为主

蓝桥杯【第13届省赛】Python B组 98.95分考完没有第一时间写题解也是因为考试时有很多不懂的,现在已经是个要打国赛的人了,重新做一下

填空题 编程题
5 分 10 分 15 分 20 分 25 分
A、B C、D E、F G、H I、J

测评链接:https://www.dotcpp.com/oj/train/1034/

A:排列字母  100🏆

【问题描述】

        小蓝要把一个字符串中的字母按其在字母表中的顺序排列。

        例如,LANQIAO 排列后为 AAILNOQ。

        又如,GOODGOODSTUDYDAYDAYUP 排列后为 AADDDDDGGOOOOPSTUUYYY

        请问对于以下字符串,排列之后字符串是什么?

        WHERETHEREISAWILLTHEREISAWAY

【解析及代码】

string = 'WHERETHEREISAWILLTHEREISAWAY'
print(''.join(sorted(string)))

You can do it if you have hands.

B:寻找整数  100🏆

【问题描述】

        有一个不超过  的正整数 n,知道这个数除以2至49后的余数如下表所示,求这个正整数最小是多少。

蓝桥杯【第13届省赛】Python B组 98.95分

【解析及代码】

因为最大的除数是 49,所以作为搜索步长 p,其对应的余数 46 作为初始值 res

如果用 for 循环进行搜索的话,那么 蓝桥杯【第13届省赛】Python B组 98.95分

假如对某一 a 存在:,此时又满足 

为了保持在更新的过程中仍然保持这两个条件,搜索步长应该更新为 (lcm 为求最小公倍数的函数):

即此时的 p 既可被原本的 49 整除,也可以被 整除,不影响原来的余数

import math

data = [0, 0, 1, 2, 1, 4, 5, 4, 1, 2, 9, 0, 5, 10,
        11, 14, 9, 0, 11, 18, 9, 11, 11, 15, 17, 9,
        23, 20, 25, 16, 29, 27, 25, 11, 17, 4, 29, 22,
        37, 23, 9, 1, 11, 11, 33, 29, 15, 5, 41, 46]
data = list(enumerate(data))[2:]

p, res = data.pop()
for m, r in data:
    # 当前结果求余结果不满足条件时
    while res % m != r: res += p
    # 求取最大公约数更新步长
    p = p * m // math.gcd(p, m)

print(res)

答案:2022040920220409

C:纸张尺寸  100🏆

【问题描述】

        在 ISO 国际标准中定义了 A0 纸张的大小为 1189mm × 841mm,将 A0 纸沿长边对折后为 A1 纸,大小为 841mm × 594mm,在对折的过程中长度直接取下整(实际裁剪时可能有损耗)。将 A1 纸沿长边对折后为 A2 纸,依此类推。 

        输入纸张的名称,请输出纸张的大小。 

【输入格式】

        输入一行包含一个字符串表示纸张的名称,该名称一定是 A0、A1、A2、A3、A4、A5、A6、A7、A8、A9 之一。 

【输出格式】

        输出两行,每行包含一个整数,依次表示长边和短边的长度。

【样例】

输入 输出
A0
1189
841
A1
841
594

【解析及代码】

x = int(input()[1])
size = [(1189, 841)]

# 当不是 A0
for time in range(x):
    last_a, last_b = size[time]
    # 原短边 -> 现长边, 长边对折
    size.append((last_b, last_a // 2))

print(*size[x], sep='\n')

D:数位排序  100🏆

【问题描述】

        小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。

        例如,2022 排在 409 前面,因为 2022 的数位之和是 6,小于 409 的数位之和 13。

        又如,6 排在 2022 前面,因为它们的数位之和相同,而 6 小于 2022。

        给定正整数 n,m,请问对 1 到 n 采用这种方法排序时,排在第 m 个的元素是多少? 

【输入格式】

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

        第二行包含一个正整数 m。

【输出格式】

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

【样例】

输入 输出 说明
13
5
3

1 13 的排序为:

1, 10, 2, 11, 3, 12, 4, 13, 5, 6, 7, 8, 9

5 个数为 3

【评测用例规模与约定】

30%
50%
100%

【解析及代码】 

import heapq

n, m = map(int, (input() for _ in range(2)))
# 求值函数: 所有数位之和
print(heapq.nsmallest(m, range(1, n + 1),
                      key=lambda x: sum(map(int, str(x))))[-1])

E:蜂巢  100🏆

【问题描述】

        蜂巢由大量的六边形拼接而成,定义蜂巢中的方向为:0 表示正西方向,1 表示西偏北 60°,2 表示东偏北 60°,3 表示正东,4 表示东偏南 60°,5 表示西偏南 60°。 

        对于给定的一点 O,我们以 O 为原点定义坐标系,如果一个点 A 由 O 点先向 d 方向走 p 步再向 (d + 2) mod 6 方向(d 的顺时针 120° 方向)走 q 步到达,则这个点的坐标定义为 (d, p, q)。在蜂窝中,一个点的坐标可能有多种。

        下图给出了点 B(0, 5, 3) 和点 C(2, 3, 2) 的示意。

蓝桥杯【第13届省赛】Python B组 98.95分

        给定点 (d1, p1, q1) 和点 (d2, p2, q2),请问他们之间最少走多少步可以到达?

【输入格式】

        输入一行包含 6 个整数 d1, p1, q1, d2, p2, q2 表示两个点的坐标,相邻两个整数之间使用一个空格分隔。

【输出格式】

        输出一行包含一个整数表示两点之间最少走多少步可以到达。 

【样例】

输入 输出
0 5 3 2 3 2 7

【评测用例规模与约定】

25%

p1, p2

50%

p1, p2

75%

p1, p2

100%

0 d1, d2 50 q1 < p1 0 q2 < p2

【解析及代码】

基本的思路是,把 (d, p, q) 坐标转换成 xy 坐标,因为 xy 坐标可叠加

转换成 xy 坐标后,可求出距离向量 (就是坐标差值),记为 (x, y)。因为研究多少步可以走完 (3, -4) 这段距离和研究多少步可以走完 (3, 4) 这段距离是等价的,故对该距离向量取绝对值

蓝桥杯【第13届省赛】Python B组 98.95分

如果 ,则从某一点回到 x 轴需要走 n 步,同时会在 x 方向上产生最多  步的移动。当然,因为在回到 x 轴的过程中,可以向左下、右下移动,所以这个  是最多,而不是一定

蓝桥杯【第13届省赛】Python B组 98.95分

蓝色的线走了 6 步,绿色的线走了 5 步,差别就是绿色的线在回到 x 轴的过程中调整过方向

总步数 = 回到 x 轴的步数 + 在 x 轴上移动的步数

import cmath


def loc_tran(d, p, q):
    # 利用复数坐标系, 求取对应方向的单位向量
    dir_tran = lambda i: cmath.rect(1, (1 - i / 3) * cmath.pi)
    # 沿 d 方向走 p 步, 沿 (d+2)%6 方向走 q 步
    return dir_tran(d) * p + dir_tran(d + 2) * q


inputs = list(map(int, input().split()))
src = loc_tran(*inputs[:3])
dst = loc_tran(*inputs[3:])
# 求出等价的距离向量
direct = dst - src
x, y = abs(direct.real), abs(direct.imag)

SQRT3 = 3 ** 0.5
# 回到 x 轴所需的步数
res = y / SQRT3 * 2
# 回到 x 轴时, 在 x 方向上产生的最大偏移量
x_move = y / SQRT3
# 在 x 方向上还需移动的步数
res += max(0, x - x_move)
print(round(res))

F:消除游戏  87🏆

【问题描述】

        在一个字符串 S 中,如果  且 蓝桥杯【第13届省赛】Python B组 98.95分,则称  和 蓝桥杯【第13届省赛】Python B组 98.95分 为边缘字符。如果  且 蓝桥杯【第13届省赛】Python B组 98.95分,则  和  也称为边缘字符。其它的字符都不是边缘字符。

        对于一个给定的串 S,一次操作可以一次性删除该串中的所有边缘字符(操作后可能产生新的边缘字符)。

        请问经过  次操作后,字符串 S 变成了怎样的字符串,如果结果为空则输出 EMPTY。 

【输入格式】

        输入一行包含一个字符串 S

【输出格式】

        输出一行包含一个字符串表示答案,如果结果为空则输出 EMPTY 

【样例】

输入 输出
edda EMPTY
sdfhhhhcvhhxcxnnnnshh s

【评测用例规模与约定】

25%

|S | ≤ ,其中 |S | 表示 S 的长度

50%

|S | ≤

75%

|S | ≤

100%

|S | ≤ S 中仅含小写字母

【解析及代码】 

import itertools as it

string = input()

for _ in range(pow(2, 63)):
    # 保存相邻字符的比较结果
    eq_flag = [string[i] == string[i + 1] for i in range(len(string) - 1)]
    # 是否保留该位置的字符
    keep_flag = [True] * len(string)
    # 是否不再出现边缘字符?
    all_done = True
    # 标记边缘字符
    for i in range(len(string) - 2):
        # S[i] == S[i+1], S[i+1] != S[i+2], 除去 S[i+1] S[i+2]
        if eq_flag[i]:
            if not eq_flag[i + 1]:
                keep_flag[i + 1] = keep_flag[i + 2] = False
                all_done = False
        # S[i] != S[i+1], S[i+1] == S[i+2], 除去 S[i] S[i+1]
        else:
            if eq_flag[i + 1]:
                keep_flag[i] = keep_flag[i + 1] = False
                all_done = False
    # 根据 keep_flag 进行保留
    string = ''.join(it.compress(string, keep_flag))
    # 退出: keep_flag 全部为 True / 字符串长度 < 3
    if all_done or len(string) < 3: break

print(string if string else 'EMPTY')

时间超限,刷不上去了

G:全排列的价值  100🏆

【问题描述】

        对于一个排列 ,定义价值  为  至  中小于  的数的个数,即 。定义 A 的价值为 

        给定 n,求 1 至 n 的全排列中所有排列的价值之和。

【输入格式】

        输入一行包含一个整数 n

【输出格式】

        输出一行包含一个整数表示答案,由于所有排列的价值之和可能很大,请输出这个数除以 998244353 的余数

【样例】

输入 输出 说明
3 9
(1 , 2 , 3) : 0 + 1 + 2 = 3
(1 , 3 , 2) : 0 + 1 + 1 = 2
(2 , 1 , 3) : 0 + 0 + 2 = 2
(2 , 3 , 1) : 0 + 1 + 0 = 1
(3 , 1 , 2) : 0 + 0 + 1 = 1
(3 , 2 , 1) : 0 + 0 + 0 = 0
故总和为 3 + 2 + 2 + 1 + 1 = 9
2022 593300958

【评测用例规模与约定】

40% n 20
70% n 5000
100%

2 n

【解析及代码】

蓝桥杯【第13届省赛】Python B组 98.95分

以 4 的全排列为例,当第一位是 2 时,总共有 种排列方式。而且每一种排列方式下必有“3 4”大于 2,贡献了 2 × 6 = 12 的价值,同理可得:

  • 第一位是 1:3 × 6 = 18
  • 第一位是 2:2 × 6 = 12
  • 第一位是 3:1 × 6 = 6
  • 第一位是 4:0 × 6 = 0

总共是 

计算完第一位产生的贡献后,剔除第一位,剩下“1 3 4”全排列产生的贡献,等价为“1 2 3”全排列产生的贡献

当现在的第一位为 1 时,总共有  种排列方式:

  • 现第一位是 1:2 × 2 = 4
  • 现第一位是 2:1 × 2 = 2
  • 现第一位是 3:0 × 2 = 0

总共是 

剔除第二位,剩下 3 4,正反两种排列总共贡献 1。全排列所有末两位的总贡献即为 

答案为 36 + 24 + 12 = 72

对于 4,全排列的价值为:蓝桥杯【第13届省赛】Python B组 98.95分

对于 n,全排列的价值为:蓝桥杯【第13届省赛】Python B组 98.95分

n = int(input())
mod = 998244353

value = n * (n - 1) / 4 % mod
for i in range(1, n + 1):
    value = value * i % mod

print(round(value))

在阶乘的时候一定要用 for 循环边乘边求余数,不要用 math 库的 factorial

H:技能升级  52🏆

【问题描述】

        小蓝最近正在玩一款 RPG 游戏。他的角色一共有 N 个可以加攻击力的技能。其中第 i 个技能首次升级可以提升  点攻击力,以后每次升级增加的点数都会减少 。 (上取整) 次之后,再升级该技能将不会改变攻击力。 

        现在小蓝可以总计升级 M 次技能,他可以任意选择升级的技能和次数。请你计算小蓝最多可以提高多少点攻击力? 

【输入格式】

        输入第一行包含两个整数 N 和 M

        以下 N 行每行包含两个整数  和

【输出格式】

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

【样例】

输入 输出
3 6
10 5
9 2
8 1
47

【评测用例规模与约定】

40% 1 N, M 1000
60%

1 N ≤ , 1 ≤ M

100%

1 N 1 M 2 ×

【解析及代码】 

这份代码的瓶颈主要在于 M 太大了,下面是比较简单的思路

读取输入之后,对  进行排序,然后每次都取出列表末端的技能 (即最大值)

将技能取出并使用后,修改技能点数,利用 bisect 库的二分法放回技能列表

import bisect

n, m = map(int, input().split())
skill = [list(map(int, input().split())) for _ in range(n)]
skill.sort()

answer = 0
for i in range(m):
    if skill[-1][0] <= 0: break
    answer += skill[-1][0]
    # 修改技能点数, 并用二分法插入
    skill[-1][0] -= skill[-1][1]
    bisect.insort(skill, skill.pop(-1))

print(answer)

I:最长不下降子序列

【问题描述】

        给定一个长度为 N 的整数序列:。现在你有一次机会,将其中连续的 K 个数修改成任意一个相同值。请你计算如何修改可以使修改后的数列的最长不下降子序列最长,请输出这个最长的长度。 

        最长不下降子序列是指序列中的一个子序列,子序列中的每个数不小于在它之前的数。

【输入格式】

        输入第一行包含两个整数 N 和 K

        第二行包含 N 个整数

【输出格式】

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

【样例】

输入 输出
5 1
1 4 2 8 5
4

【评测用例规模与约定】

20% 1 K N 100
30% 1 K N 1000
50% 1 K N 10000
100%

1 K N 1 Ai

【解析及代码】

我有个可以找到最优解的思路,不过要写的话代码太多,懒得做。从左到右做个递增序列的搜索,从右到左做个递增序列的搜索,变换成两个递增序列的拼接问题

挂个 C++ 大佬的满分做法:Link ~

J:最优清零方案  24🏆

【问题描述】

        给定一个长度为 N 的数列 。现在小蓝想通过若干次操作将这个数列中每个数字清零。

        每次操作小蓝可以选择以下两种之一:

        1. 选择一个大于 0 的整数,将它减去 1;

        2. 选择连续 K 个大于 0 的整数,将它们各减去 1。

        小蓝最少经过几次操作可以将整个数列清零?

【输入格式】

        输入第一行包含两个整数 N 和 K

        第二行包含 N 个整数

【输出格式】

        输出一个整数表示答案

【样例】

输入 输出
4 2
1 2 3 4
6

【评测用例规模与约定】

20% 1 K N 10
40% 1 K N 100
50% 1 K N 1000
60% 1 K N 10000
70% 1 K N 100000
100% 1 K N 1000000, 0 Ai 1000000

【解析及代码】

从测试结果来看,只对了一部分样例,这个并不是最优的做法,接下来讲讲怎么一本正经的骗分

对于 3 1 2 4 5,操作长度为 3 时,最优的操作应当是:

  1. 操作二 1 次:2 0 1 4 5
  2. 操作一 2 次:0 0 1 4 5
  3. 操作二 1 次:0 0 0 3 4
  4. 操作二 3 次:0 0 0 0 1
  5. 操作一 1 次:0 0 0 0 0

如果将两种操作合并成“链式减 1”,则上述操作等价于:

  1. 操作 3 次:[0, 1, 2] 位置减去 [3, 1, 1] -> 0 0 1 4 5
  2. 操作 1 次:[2, 3, 4] 位置减去 [1, 1, 1] -> 0 0 0 3 4
  3. 操作 3 次:[3, 4] 位置减去 [3, 3] -> 0 0 0 0 1
  4. 操作 1 次:[4] 位置减去 [1] -> 0 0 0 0 0

在某一轮链式减 1 中,该区间首元素的数值即为操作数 (直接将首元素置 0),其它元素的减少量不高于上一位的减少量、不高于本身数值文章来源地址https://www.toymoban.com/news/detail-408056.html

n, k = map(int, input().split())
seq = list(map(int, input().split()))

# 记录操作次数
time, pin = 0, 0
while pin < n:
    if seq[pin]:
        # 操作次数 = 当前 pin 指向的值
        time += seq[pin]
        # 链式操作量: 必是降序
        sub_list = [seq[pin]]
        seq[pin] = 0
        # 操作不超过限制个数的数
        for next_ in range(pin + 1, min([pin + k, n])):
            # 计算可减少的量
            sub = min([sub_list[-1], seq[next_]])
            if sub == 0: break
            # 存储减少量, 并减少
            sub_list.append(sub)
            seq[next_] -= sub
    pin += 1

print(time)

到了这里,关于蓝桥杯【第13届省赛】Python B组 98.95分的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 蓝桥杯2023年第十四届省赛-飞机降落

    N 架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 Ti 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 Di 个单位时间,即它最早 可以于 Ti 时刻开始降落,最晚可以于 Ti + Di 时刻开始降落。降落过程需要 Li个单位时间。 一架飞机降落完毕时,另一架

    2024年02月15日
    浏览(56)
  • 【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-填空题

    目录 试题A:门牌制作 解题思路: 答案: 试题B:既约分数 解题思路: 答案: 试题C:蛇形填数 解题思路: 答案: 试题D:跑步训练 解题思路: 答案: 试题E:七段码 解题思路: 答案: 写在最后: 小蓝要为一条街的住户制作门牌号。 这条街一共有 2020 位住户,门牌号从

    2023年04月19日
    浏览(68)
  • 【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-编程题

    目录 试题F:成绩统计 解题思路: 代码: 试题G:回文日期 解题思路: 代码: 试题H:字串分值 解题思路: 代码:  试题I:平面切分 解题思路: 代码: 试题J:字串排序 解题思路: 写在最后: 【问题描述】 小蓝给学生们组织了一场考试,卷面总分为 100 分, 每个学生的

    2024年02月02日
    浏览(44)
  • 【蓝桥杯冲刺】蓝桥杯12届省赛C++b组真题-编程题

    目录 试题F:时间显示 解题思路 代码 试题G:砝码称重 解题思路 代码 试题H:杨辉三角 解题思路 代码 试题I:双向排序 解题思路 试题J:括号序列 解题思路 【问题描述】 小蓝要和朋友合作开发一个时间显示的网站。 在服务器上,朋友已经获取了当前的时间,用一个整数表

    2023年04月16日
    浏览(40)
  • 【蓝桥杯冲刺】蓝桥杯12届省赛C++b组真题-填空题

    目录 试题A:空间 解题思路 答案 试题B:卡片 解题思路 答案 试题C:直线 解题思路 答案 试题D:货物摆放 解题思路 答案 试题E:路径 解题思路 答案 ​编辑 写在最后: 小蓝准备用 256 MB 的内存空间开一个数组, 数组的每个元素都是 32 位二进制整数, 如果不考虑程序占用的

    2024年02月03日
    浏览(45)
  • 蓝桥杯单片机学习14——第十三届省赛题

    上期我们学习了NE555方波发生器频率测量,讲到我会更新之后省赛的题目,那么,他来了。 首先声明:我还没有参加蓝桥杯单片机比赛,也没有拿过奖,所以我写的代码注定不会那么完美,存在BUG是必然的,我写这个系列的目的纯粹是为了记录我的学习………… 关于功能描述

    2024年02月06日
    浏览(57)
  • 蓝桥杯单片机学习15——第十二届省赛题

    书接上文,上期我们基本完成了十三届省赛题,但还是存在一些问题,本期我将对上期存在的一些问题,提出一些解决方案,并加以实践验证可行性,废话少说,让我们往下看。 上期我们提到,数码管和LED在使用的时候会存在外设之间相互干扰的问题,在我们不断的探索之下

    2024年01月25日
    浏览(61)
  • 蓝桥杯嵌入式第十四届省赛题目解析

    前几天刚刚参加完第十四届的省赛,这届题目比我想象中的要难,其实想一想这也是应该的,以前的知识点都被摸透了,也是需要加入新的知识点了,但是我还是想说能不能别在我参加的时候加大题目难度啊。 不过听说隔壁单片机的省赛都比往年的国赛还难,这就有点离谱了

    2024年02月06日
    浏览(58)
  • 【蓝桥杯单片机】第十二届省赛(含题目和解答代码)

    main.c  iic.c iic.h onewire.c onewire.h      

    2024年02月04日
    浏览(72)
  • 蓝桥杯2023年第十四届省赛真题-平方差--题解

    时间限制: 3s 内存限制: 320MB 提交: 2379 解决: 469 给定 L, R,问 L ≤ x ≤ R 中有多少个数 x 满足存在整数 y,z 使得 x = y2 − z2。 输入一行包含两个整数 L, R,用一个空格分隔。 输出一行包含一个整数满足题目给定条件的 x 的数量。 复制 复制 1 = 1^2 − 0^2 ; 3 = 2^2 − 1^2 ; 4 =

    2024年02月07日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包