蓝桥杯第15届(2024年4月)

第一次参加蓝桥杯总结与反思:

赛前状态反思:

赛前那段时间,确实不够努力,没有完全执行自己和老师制定的计划,没有充分利用时间去进行算法训练,过于松懈了。虽然后来在老师的指点下,开始认真总结写过的算法题,但是做题的数量还是远远不够。

赛中状态反思:

比赛时候,紧张,慌乱,害怕,各种情绪交杂在一起,加上考场出现的一些突发情况,前一个小时我几乎不能平静下来认真做题。做题过程中也是手忙脚乱,瞻前顾后。

赛后反思总结:

比赛完之后,我第一个想法就是,备战第16届蓝桥杯。因为这次的蓝桥杯让我对比赛有了初步的认识,我也意识到,学习算法和积累沉淀的重要性。我在往后学习和生活中需要做的,一是在比赛或者其他重要考试或者大场合中能够做到临危不惧,及时调整好自己的状态,找到属于自己的节奏;二是不打无准备的仗,这次蓝桥杯比赛显然我准备的还远远不够充分,不够扎实;三是自律、严格执行计划,计划制定完成之后,应该严格执行,这是我需要改正的。在写这届蓝桥杯题目分析的时候,我上网看到了好多方法,里面解决问题调用的函数里面有些甚至我非常陌生,一是我能力不够,二是我没好好利用帮助文档。

总之,这次蓝桥杯我写得很失败,但无疑是给我沉重一击,给我很多的启发,让我及时端正学习态度,时常反思,时常进步。

题目分析:

关于题目的解题过程和思路,我在整理的时候,会先写出我比赛时的思路,也会写出在网上查找到的一些思路和方法。这里面或许会有错误,在看到优秀的题解我也会及时补充进来。

题目A:穿越时空之门

【问题描述】

随着2024年的钟声回荡,传说中的时空之门再次敞开。这扇门是一条神秘的通道,它连接着二进制和四进制不同的数码领域,等待着勇者们的探索。

在二进制的领域里,勇者的力量被转换成力量数值的二进制表示各数位之和。

在四进制的领域里,力量的转换规则相似,变成了力量数值的四进制表示中各数位之和。

穿越这扇时空之门的条件是严苛的:当且仅当勇者在二进制领域的力量时,他才能够成功地穿越。

国王选定了小蓝作为领路人,带领着力量值从1到2024的勇者们踏上了这段探索未知的旅程。作为小蓝的助手,你的任务是帮助小蓝计算出,在这2024位勇者中,有多少人符合穿越时空之门的条件。

 🤔数字转二进制、四进制,数位之和相等

答案:63

def sum_jinzhi(a,k):
    """将数字a转换为k进制,求数值位和"""
    sum=0
    while a!=0:
        sum+=a%k
        a=a//k
    return sum

num=0
for i in range(1,2024):
    if sum_jinzhi(i,2)==sum_jinzhi(i,4):
        num+=1
print(num)

题目B:数字串个数

【问题描述】

小蓝想要构造出一个长度为10000的数字字符串 ,有以下要求:

1、小蓝不喜欢数字0,所以数字字符串中不可以出现0

2、小蓝不喜欢数字3和7,所以数字字符串中必须有3和7这两个数字

请问满足题意的数字字符串有多少个?这个数字会很大,只需要输出对10**9+7取余后的结果

🤔当时想着暴力解决,但是会出现下面的报错

"Exceeds the limit (4300 digits) for integer string conversion"表示整数字符串转换时超过了限制,限制为4300位数字。要解决这个问题,可以使用sys.set_int_max_str_digits()函数来增加限制。sys.set_int_max_str_digits()函数是Python中的一个函数,用于设置整数字符串转换的最大位数限制。通过调用该函数并传入一个较大的值,可以增加整数字符串转换的限制。

可以这样解决,sys.set_int_max_str_digits(0),表示没有限制

但是这样运行时间太长 ,但代入小数值运行结果正确的

🤔更好的方法:容斥原理

容斥原理:先不考虑重叠情况,把包含于某内容种的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数方法叫做容斥原理。

本题运用容斥原理的解题思路:

首先考虑每一位数字的选择。由于数字字符串中不能出现0,所以每一位数字有9种选择(1-9)。因此,长度位10000的数字字符串有pow(9,n)种可能性。

题目要求必须包含3和7,因此需要减去不包含3和7的情况。不包含3有pow(8,n)种,不包含7的有pow(8,n)种。

但是上述操作会将同时不含3和7的情况计算两次,因此需要再加回来。即不含3也不含7的情况有pow(7,n)种。

综上,满足的数字字符串数量为pow(9,n)-2*pow(8,n)+pow(7,n)。

最后对结果取mod=int(1e9+7)的余数

pow(x,y,z)函数:

x:底数,不可省        y:指数,不可省

z:取余数字,可省,当z存在时,函数返回值等于pow(x,y)%z

答案:157509472

mod=int(1e9+7)
n=10000
cnt=pow(9,n)
cnt-=2*pow(8,n)
cnt+=pow(7,n)
cnt%=mod
print(cnt)

题目C:连连看

【问题描述】

小蓝在和朋友们玩一种新的连连看游戏。在一个n*m的矩形网格中,每个格子中都有一个整数,第i 行第j 列上的整数为Ai,j,玩家需要在这个网格中寻找一对格子(a,b)-(c,d)使得这两个格子中的整数Aa,b和Ac,d相等,且它们的位置满足|a-c|=|b-d|>0。请问在这个n*m的矩形网格中有多少对这样的格子满足条件。

【输入格式】

输入的第一行包含两个正整数n,m,用一个空格分隔。

接下来的n行,第i 行包含m个正整数Ai,1、Ai2、.....Ai,m,相邻整数之间使用一个空格分隔。

【输出格式】

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

【样例】

输入:

3 2

1 2

2 3

3 2

输出:

6

说明:

一共有以下6对格子:(1,2)-(2,1),(2,2)-(3,1),(2,1)-(3,1),(2,1)-(1,2),(3,1)-(2,2),(3,2)-(2,1)。

【评测用例规模与约定】

20%         1<=n,m<=50

100%        1<=n,m<=1000,1<=Ai,j<=1000

 由题意可知,(a,b)-(c,d)中的两个元素位于同一斜线上

n, m = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(n)]
 
# A[a][b] = A[c][d], 处于同一斜线上
cnt = 0
for i in range(n):
    for j in range(m):
        # 只跟当前行以下的行比较
        # 向左下角
        for p in range(1, min(n - i, j + 1)):
            cnt += A[i][j] == A[i + p][j - p]
        # 向右下角
        for p in range(1, min(n - i, m - j)):
            cnt += A[i][j] == A[i + p][j + p]
print(cnt * 2)

题目D:神奇闹钟

【问题描述】

小蓝发现了一个神奇的闹钟,从纪元时间(1970年1月1日00:00:00)开始,每经过x分钟,这个闹钟便会触发一次响铃(纪元时间也会响铃)。这引起了小蓝的兴趣,他想要好好研究一下这个闹钟。

对于给出的任意一个格式为yyyy-MM-dd HH:mm:ss的时间,小蓝想要知道在这个时间点之前(包含这个时间点)的最近的一次闹铃时间是哪个时间?

注意,你不必考虑时区问题。

【输入格式】

输入的第一行包含一个整数T,表示每次输入包含T组数据。

接下来依次描述T组数据。

每组数据一行,包含一个时间(格式为yyyy-MM-dd HH:mm:ss)和一个整数x,其中x表示闹铃时间间隔(单位为分钟)。

【输出格式】

输出T行,每行包含一个时间(格式为yyyy-MM-dd HH:mm:ss),依次表示每组数据的答案。

【样例】

输入:

2

2016-09-07 18:24:33 10

2037-01-05 01:40:43 30

输出:

2016-09-07 18:20:00

2037-01-05 01:30:00 

【评测用例规模与约定】

100%        1<=T<=10,1<=x<=1000

 🤔当时想的是计算出来两个时间相差多少分钟,其中包含闰年的判断等等,其中结果的秒必是00,很难计算,最后也没写出来。

🤔下面这种方法是在网上看到的,很厉害。但这涉及到我的知识盲区了😵,部分函数方法我几乎没用过。

import time
fmt="%Y-%m-%d %H:%M:%S"
for i in range(int(input())):
    #从最右边开始,进行一次拆分,以空格分隔
    datetime,x=input().rsplit(maxsplit=1)
    #x是分钟表示,乘以60,以秒表示
    x=int(x)*60
    #t为输入的时间与纪元时间所差的秒数,四舍五入。
    t=round(time.mktime(time.strptime(datetime,fmt)))
    print(time.strftime(fmt,time.localtime(t-t%x)))

str.rsplit(sep=None,maxsplit=-1)

   描述:

返回一个由字符串内单词组成的列表,使用sep作为分隔字符串。

如果给出了maxsplit,则最多进行maxsplit次拆分,从最右边开始。

除了从右边开始拆分,rsplit()的其他行为都类似与split()。

   参数说明:

sep:分隔符,默认为所有的空格符,包括空格、换行(\n),制表符(\t)等。

maxsplit:分割次数,默认为-1,即分割所有

   返回值:返回分割后的字符串列表。

 round()是python中自带的一个函数,用于数字的四舍五入。但round()的输出结果和python的版本有关:在python3中,round(1.0/2.0)=0;在python2中,round(1.0/2.0)=1

round(number,digits)

①digits>0,四舍五入到指定的小数位

②digits=0,四舍五入到最接近的整数

③digits<0,在小数点左侧进行四舍五入

④如果只有number一个参数,相当于digits=0

四舍五入规则:

①要求保留位数的后一位小于等于4,则舍去。

如5.214,保留小数点后两位,5.21

②要求保留位数的后一位等于5,且该位数后无数字,则不进位,直接舍去。

如5.215,保留小数点后两位,5.21

③要求保留位数的后一位等于5,且该位数后有数字,则进位

如5.2151,保留小数点后两位,2.22

④要求保留位数的后一位大于等于6,则进位。

如5.216,保留小数点后两位,5.22

time.mktime(t) 

参数:t:结构化的时间或者完整的9位元组元素。

返回值:返回用描述来表示时间的浮点数,返回自1970年1月1日00:00:00到现在所经过的秒数。

如果输入的值不是一个合法的时间,将触发OverflowError或ValueError。

例:

import time
t = (2009, 2, 17, 17, 3, 38, 1, 48, 0)
secs = time.mktime( t )        #1234915418.000000

time.strftime(format[,t])

描述:用于格式化时间,返回以可读字符串表示当地时间,格式由参数format决定。

参数:format:格式字符串。        t:可选参数,是一个struct_time对象

返回值:返回以可读字符串表示当地时间。

  

time.strptime(string[,format])

描述:根据指定格式把一个时间字符串解析为时间元组。

参数:string:时间字符串。        format:格式化字符串。

返回值:返回struct_time对象。

经过这题,我意识到,时间的相关函数需要专门去学习一下。

题目E:蓝桥村的真相

【问题描述】

在风景如画的蓝桥村,n 名村民围坐在一张古老的圆桌旁,参与一场思想 的较量。这些村民,每一位都有着鲜明的身份:要么是誉满乡野的诚实者,要 么是无可救药的说谎者。

当会议的钟声敲响,一场关于真理与谬误的辩论随之展开。每位村民轮流 发言,编号为 i 的村民提出了这样的断言:坐在他之后的两位村民------也就是 编号 i + 1 和 i + 2(注意,编号是环形的,所以如果 i 是最后一个,则 i + 1 是 第一个,以此类推)之中,一个说的是真话,而另一个说的是假话。

在所有摇曳不定的陈述中,有多少真言隐藏在谎言的面纱之后?

请你探索每一种可能的真假排列组合,并计算在所有可能的真假组合中, 说谎者的总数。

【输入格式】

输入的第一行包含一个整数 T,表示每次输入包含 T 组数据。

接下来依次描述 T 组数据。

每个数据一行包含一个整数 n,表示村落的人数。

【输出格式】

输出 T 行,每行包含一个整数,依次表示每组数据的答案。

【样例】

输入:

2

3

3

输出:

6

6

【评测用例规模与约定】

10%        T=1,3<=n<=10

40%        1<=T<=10**2,3<=n<=3*10**3

100%        1<=T<=10**5,3<=n<=10**18

🤔这题我当时第一反应是动态规划,但是没写出来状态转移方程。不了了之。

🤔下面是网上一种解法:

找规律

num=int(input())
re=[]
for i in range(num):
    n=int(input())
    re.append(n*((n+1)//2))
for i in range(num):
    print(re[i])

!!题目F:魔法巡游

【问题描述】

        在蓝桥王国中,两位魔法使者,小蓝与小桥,肩负着维护时空秩序的使命。 他们每人分别持有 N 个符文石,这些石头被赋予了强大的力量,每一块上都刻 有一个介于 1 到  之间的数字符号。小蓝的符文石集合标记为S1,S2,.......Sn , 小桥的则为t1,t2,.....tn 。

        两位魔法使者的任务是通过使用符文石,在各个时空结点间巡游。每次巡游遵循这样一条法则:当小蓝使用了符文石 Si到达新的结点后,小桥必须选用 一个序号更大的符文石(即某个tj满足 j > i)前往下一个结点。同理,小桥抵 达之后,小蓝需要选择一个序号 k > j 的符文石Sk继续他们的巡游。

        为了成功地穿梭时空,两个连续使用的符文石上的数字符号必须有共鸣, 这种共鸣只有当数字符号中至少包含一个特定的元素——星火(数字 0)、水波 (数字 2)或者风语(数字 4)时,才会发生。例如,符号序列 126, 552, 24, 4 中 的每对连续符文都包含了至少一个共鸣元素,则它们是一系列成功的巡游;而 如果是 15, 51, 5,则不成立,因为它们之间的共鸣元素不包含星火、水波或风语 中的任意一个。

        小蓝总是先启程,使用他的符文石开启巡游。

        你的任务是计算这对魔法使者能够执行的最长时空巡游序列的长度。这样的序列形式为 si,iti2,si3,ti4,......其中序列索引满足i1<i2<i3<i4<....... ,并且序列中每一对相邻的符文石都至少包含一个共鸣元素。

【输入格式】

        输入的第一行包含一个整数 N,表示每位魔法使者持有的符文石数量。

        第二行包含 N 个整数 s1,s2,....sn,相邻整数之间使用一个空格分隔,表示小蓝的符文石上刻有的数字符号。

        第三行包含 N 个整数 t1,t2,....tn ,相邻整数之间使用一个空格分隔,表示小桥的符文石上刻有的数字符号。

【输出格式】

        输出一行包含一个整数,表示小蓝和小桥在遵守所有规则的情况下,最多能进行多少次时空巡游。

【样例】

输入:

5

126 393 581 42 44

204 990 240 46 52

输出:

4

说明:小蓝和小桥可以选择以下符文石序列进行巡游:S1(126)->t3(240)->s4(42)->t5(52)这里,数字2作为共鸣元素连接了s1和t3、s4和t5,数字2、4作为共鸣元素连接了t3和s4。

【评测用例规模与约定】

30%        1<=N<=10**3,1<=si,ti<=10**5

100%        1<=N<=10**5,1<=si,ti<=10**9

!!!题目G:缴纳过路费

【问题描述】

在繁华的商业王国中,N 座城市被 M 条商路巧妙地连接在一起,形成了一 个错综复杂的无向图网络。每条商路是双向通行的,并且任意两座城市之间最 多只有一条直接的商路。每条商路都有它的规则,其中最引人注目的就是穿过商路,需要缴纳过路费。因此,商人们在选择商路时必须格外认真。

有一位名叫小蓝的商人,他对于商路的花费有着自己独到的见解。在小蓝 眼中,一条路线包含一条或多条商路,但路线的成本并不是沿途累积的过路费 总和,而是这条路线上最贵的那一次收费。这个标准简单而直接,让他能迅速 评估出一条路线是否划算。

于是,他设立了一个目标,即找出所有城市对,这些城市之间的最低路线 成本介于他心中预设的两个数 L 和 R 之间。他相信,这样的路线既不会太廉 价,以至于路况糟糕;也不会过于昂贵,伤害他精打细算的荷包。

作为小蓝的助手,请你帮助小蓝统计出所有满足条件的城市对数量。

【输入格式】

输入的第一行包含四个整数 N, M, L, R,表示有 N 座城市和 M 条双向通行 的商路,以及小蓝心中预设的最高过路费的下限 L 和上限 R。

接下来 M 行,每行包含三个整数 u, v, w,表示城市 u 和城市 v 之间有一条 双向通行的商路,过路费为 w。保证每对城市之间最多只有一条直接的商路。

【输出格式】

输出一行包含一个整数,表示满足条件的城市对数量。

【样例】

输入:

5 5 1 2

1 2 2

1 3 5

1 4 1

2 4 5

2 5 4

输出:

3

说明:

满足条件的城市对有(1,2),(1,4),(2,4)

!!!题目H:纯职业小组

【问题描述】

在蓝桥王国,国王统治着一支由 n 个小队组成的强大军队。每个小队都由相同职业的士兵组成。具体地,第 i 个小队包含了 bi 名职业为 ai 的士兵。

近日,国王计划在王宫广场举行一场盛大的士兵检阅仪式,以庆祝王国的繁荣昌盛。然而,在士兵们入场的过程中,一场突如其来的风暴打乱了他们的 行列,使得不同小队的士兵混杂在一起,次序乱成一团,尽管国王无法知道每个士兵的具体职业,但为了确保仪式能顺利进行,国王打算从这些混乱的士兵中选出一部分,组成 k 个"纯职业小组"进行检阅。 一个"纯职业小组"定义为由 3 名同职业的士兵组成的队伍。

请问,国王至少需要选择多少名士兵,才能确保这些士兵可以组成 k 个 "纯职业小组"。

【输入格式】

输入的第一行包含一个整数 T,表示每次输入包含 T 组数据。

接下来依次描述 T 组数据。

每组数据的第一行包含两个整数 nt和 k ,用一个空格分隔,表示小队的数量和要组成的纯职业小组的数量。

接下来的 nt行,每行包含两个整数ai  和bi  ,用一个空格分隔,表示第 i 个小队中士兵的职业和数量。

【输出格式】

输出 T 行,每行包含一个整数,依次表示每组数据的答案,即为了组成 k 个"纯职业小组",国王至少需要选择的士兵数量。如果无论如何也无法组成 k 个"纯职业小组",则输出 −1。

  • 32
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值