第十四届蓝桥杯python第一期模拟赛

文章目录

  • 第十四届蓝桥杯python第一期模拟赛
    • 1. 二进制位数
      • 问题描述
      • 答案提交
      • 思路
      • 参考答案
    • 2. 晨跑
      • 问题描述
      • 答案提交
      • 思路
      • 参考答案
    • 3. 调和级数
      • 问题描述
      • 答案提交
      • 思路
      • 参考答案
    • 4. 山谷
      • 问题描述
      • 答案提交
      • 思路
      • 参考答案
    • 5. 最小矩阵
      • 问题描述
      • 答案提交
      • 思路
      • 参考答案
    • 6. 核酸日期
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 评测用例规模与约定
      • 思路
      • 参考代码
    • 7. 英文转换
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 评测用例规模与约定
      • 思路
      • 参考代码
    • 8. 充电器
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 评测用例规模与约定
      • 思路
      • 参考代码
    • 9. 全相等三角形
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入1
      • 样例输出1
      • 样例输入2
      • 样例输出2
      • 评测用例规模与约定
      • 思路
      • 参考代码
    • 10. 最小下标
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入1
      • 样例输出1
      • 样例输入2
      • 样例输出2
      • 评测用例规模与约定
      • 思路
      • 参考代码
        • 暴力法
      • 最小表示法

蓝桥杯官方给了一个机会给我们可以尝试这个第一期模拟赛,那我们就试一下吧,学习学习一下,也给大家一点借鉴嘻嘻,也都不一定对哦,仅供参考。
2022/11/8,填空题已完成
2022/11/9,已做678,剩下9,10
2022/11/12,9更新
2022/11/16,10更新,已全部完成
2022/11/17,更新2不用库的做法

1. 二进制位数

问题描述

十进制整数 2 在十进制中是 1 位数,在二进制中对应 10 ,是 2 位数。
十进制整数 22 在十进制中是 2 位数,在二进制中对应 10110 ,是 5 位数。
请问十进制整数 2022 在二进制中是几位数?

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

这道题对于其他人来说,可能还稍微麻烦了,但是对于python说,几乎秒杀,只需要用python的bin函数,就可以迅速将十进制转成二进制,然后再减去首字母的两个0b即可。

参考答案

11

print(len(bin(2022))-2)

2. 晨跑

问题描述

小蓝每周六、周日都晨跑,每月的 1、11、21、31日也晨跑。其它时间不晨跑。
已知 2022年1月1日是周六,请问小蓝整个2022年晨跑多少天?

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

这道题对于python来说,也是有技巧的,其实我们只需要判断2022年中,从头遍历到尾,然后筛选周六周日的时间,和每月的1,11,21,31日,累加即可,巧用python,善用python

datetime参考资料

Python–time, datetime库常用方法
python——datetime库用法

参考答案

138

import datetimestart = datetime.datetime(year=2022,month=1,day=1) # 定义头为2022.1.1
end = datetime.datetime(year=2023,month=1,day=1) # 尾为2023.1.1
cnt = 0 # 计数
while start != end: # 当没到下一年的时候,也就是遍历2022全年if start.isoweekday() in [6,7] or start.day in [1,11,21,31]:cnt += 1  # 小蓝每周六、周日都晨跑,每月的 1、11、21、31日也晨跑。start += datetime.timedelta(days=1) # 下一天print(cnt)

有人还问,不用库怎么写,其实也是可以的,只是我们可以利用python的优势哈哈

week = 6 # 周六
cnt = 0
month = [0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
for i in range(1,13):for j in range(1,month[i]+1): if week == 6 or week == 0 or j == 1 or j == 11 or j == 21 or j == 31:cnt += 1week += 1week = week%7
print(cnt)

3. 调和级数

问题描述

小蓝特别喜欢调和级数 S(n)=1/1+1/2+1/3+1/4+…+1/n 。
请问,n 至少为多大时,S(n)>12 ?

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

其实这道题思路很简单,只要我们不断的加,直到满足条件,我们就停下即可

参考答案

91380

s = 0
i = 1
while s <= 12:s += 1.0/ii += 1
print(i-1) # 不用加最后一次

4. 山谷

问题描述

给定一个字母矩阵,如果矩阵中的某个位置不在四条边上,而且该位置上的字母小于其上下左右四个位置的字母,则称为一个山谷。
例如,对于如下矩阵

DDDDD
CADCE
FFFFA

共有两个山谷,位于第二行第二列和第四列。请注意第二行第三列和第三行第五列都不是山谷。
对于如下30行60列的字母矩阵(请用等宽字体查看),请问有多少个山谷?

PHQGHUMEAYLNLFDXFIRCVSCXGGBWKFNQDUXWFNFOZVSRTKJPREPGGXRPNRVY
STMWCYSYYCQPEVIKEFFMZNIMKKASVWSRENZKYCXFXTLSGYPSFADPOOEFXZBC
OEJUVPVABOYGPOEYLFPBNPLJVRVIPYAMYEHWQNQRQPMXUJJLOOVAOWUXWHMS
NCBXCOKSFZKVATXDKNLYJYHFIXJSWNKKUFNUXXZRZBMNMGQOOKETLYHNKOAU
GZQRCDDIUTEIOJWAYYZPVSCMPSAJLFVGUBFAAOVLZYLNTRKDCPWSRTESJWHD
IZCOBZCNFWLQIJTVDWVXHRCBLDVGYLWGBUSBMBORXTLHCSMPXOHGMGNKEUFD
XOTOGBGXPEYANFETCUKEPZSHKLJUGGGEKJDQZJENPEVQGXIEPJSRDZJAZUJL
LCHHBFQMKIMWZOBIWYBXDUUNFSKSRSRTEKMQDCYZJEEUHMSRQCOZIJIPFION
EEDDPSZRNAVYMMTATBDZQSOEMUVNPPPSUACBAZUXMHECTHLEGRPUNKDMBPPW
EQTGJOPARMOWZDQYOXYTJBBHAWDYDCPRJBXPHOOHPKWQYUHRQZHNBNFUVQNQ
QLRZJPXIOGVLIEXDZUZOSRKRUSVOJBRZMWZPOWKJILEFRAAMDIGPNPUUHGXP
QNJWJMWAXXMNSNHHLQQRZUDLTFZOTCJTNZXUGLSDSMZCNOCKVFAJFRMXOTHO
WKBJZWUCWLJFRIMPMYHCHZRIWKBARXBGFCBCEYHJUGIXWTBVTREHBBCPXIFB
XVFBCGKCFQCKCOTZGKUBMJRMBSZTSSHFROEFWSJRXJHGUZYUPZWWEIQURPIX
IQFLDUUVEOOWQCUDHNEFNJHAIMUCZFSKUIDUBURISWTBRECUYKABFCVKDZEZ
TOIDUKUHJZEFCZZZBFKQDPQZIKFOBUCDHTHXDJGKJELRLPAXAMCEROSWITDP
TPCCLIFKELJYTIHRCQAYBNEFXNXVGZEDYYHNGYCDRUDMPHMECKOTRWOSPOFG
HFOZQVLQFXWWKMFXDYYGMDCASZSGOVSODKJGHCWMBMXRMHUYFYQGAJQKCKLZ
NAYXQKQOYZWMYUBZAZCPKHKTKYDZIVCUYPURFMBISGEKYRGZVXDHPOAMVAFY
RARXSVKHTQDIHERSIGBHZJZUJXMMYSPNARAEWKEGJCCVHHRJVBJTSQDJOOTG
PKNFPFYCGFIEOWQRWWWPZSQMETOGEPSPXNVJIUPALYYNMKMNUVKLHSECDWRA
CGFMZKGIPDFODKJMJQWIQPUOQHIMVFVUZWYVIJGFULLKJDUHSJAFBTLKMFQR
MYJFJNHHSSQCTYDTEAMDCJBPRHTNEGYIWXGCJWLGRSMEAEARWTVJSJBAOIOJ
LWHYPNVRUIHOSWKIFYGTYDHACWYHSGEWZMTGONZLTJHGAUHNIHREQGJFWKJS
MTPJHAEFQZAAULDRCHJCCDYRFVVRIVUYEEGFIVDRCYGURQDREDAKUBNFGUPR
OQYLOBCWQXKZMAUSJGMHCMHGDNMPHNQKAMHURKTRFFACLVGRZKKLDACLLTEO
JOMONXRQYJZGINRNNZWACXXAEDRWUDXZRFUSEWJTBOXVYNFHKSTCENAUMNDD
XFDMVZCAUTDCCKXAAYDZSXTTOBBGQNGVVPJGOJOGLMKXGBFCPYPCKQCHBDDZ
WRXBZMQRLXVOBTWHXGINFGFRCCLMZNMJUGWWBSQFCIHUBSJOLLMSQSGHMCPH
ELSOTFLBGSFNPCUZSRUPCHYNVZHCPQUGRIWNIQXDFJPWPXFBLKPNPEELFJMT

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

这道题,其实很简单,我们可以用暴力即可解决,只需要判断该位置上的字母小于其上下左右四个位置的字母,符合条件则累加即可。

参考答案

276

m = '''PHQGHUMEAYLNLFDXFIRCVSCXGGBWKFNQDUXWFNFOZVSRTKJPREPGGXRPNRVY
STMWCYSYYCQPEVIKEFFMZNIMKKASVWSRENZKYCXFXTLSGYPSFADPOOEFXZBC
OEJUVPVABOYGPOEYLFPBNPLJVRVIPYAMYEHWQNQRQPMXUJJLOOVAOWUXWHMS
NCBXCOKSFZKVATXDKNLYJYHFIXJSWNKKUFNUXXZRZBMNMGQOOKETLYHNKOAU
GZQRCDDIUTEIOJWAYYZPVSCMPSAJLFVGUBFAAOVLZYLNTRKDCPWSRTESJWHD
IZCOBZCNFWLQIJTVDWVXHRCBLDVGYLWGBUSBMBORXTLHCSMPXOHGMGNKEUFD
XOTOGBGXPEYANFETCUKEPZSHKLJUGGGEKJDQZJENPEVQGXIEPJSRDZJAZUJL
LCHHBFQMKIMWZOBIWYBXDUUNFSKSRSRTEKMQDCYZJEEUHMSRQCOZIJIPFION
EEDDPSZRNAVYMMTATBDZQSOEMUVNPPPSUACBAZUXMHECTHLEGRPUNKDMBPPW
EQTGJOPARMOWZDQYOXYTJBBHAWDYDCPRJBXPHOOHPKWQYUHRQZHNBNFUVQNQ
QLRZJPXIOGVLIEXDZUZOSRKRUSVOJBRZMWZPOWKJILEFRAAMDIGPNPUUHGXP
QNJWJMWAXXMNSNHHLQQRZUDLTFZOTCJTNZXUGLSDSMZCNOCKVFAJFRMXOTHO
WKBJZWUCWLJFRIMPMYHCHZRIWKBARXBGFCBCEYHJUGIXWTBVTREHBBCPXIFB
XVFBCGKCFQCKCOTZGKUBMJRMBSZTSSHFROEFWSJRXJHGUZYUPZWWEIQURPIX
IQFLDUUVEOOWQCUDHNEFNJHAIMUCZFSKUIDUBURISWTBRECUYKABFCVKDZEZ
TOIDUKUHJZEFCZZZBFKQDPQZIKFOBUCDHTHXDJGKJELRLPAXAMCEROSWITDP
TPCCLIFKELJYTIHRCQAYBNEFXNXVGZEDYYHNGYCDRUDMPHMECKOTRWOSPOFG
HFOZQVLQFXWWKMFXDYYGMDCASZSGOVSODKJGHCWMBMXRMHUYFYQGAJQKCKLZ
NAYXQKQOYZWMYUBZAZCPKHKTKYDZIVCUYPURFMBISGEKYRGZVXDHPOAMVAFY
RARXSVKHTQDIHERSIGBHZJZUJXMMYSPNARAEWKEGJCCVHHRJVBJTSQDJOOTG
PKNFPFYCGFIEOWQRWWWPZSQMETOGEPSPXNVJIUPALYYNMKMNUVKLHSECDWRA
CGFMZKGIPDFODKJMJQWIQPUOQHIMVFVUZWYVIJGFULLKJDUHSJAFBTLKMFQR
MYJFJNHHSSQCTYDTEAMDCJBPRHTNEGYIWXGCJWLGRSMEAEARWTVJSJBAOIOJ
LWHYPNVRUIHOSWKIFYGTYDHACWYHSGEWZMTGONZLTJHGAUHNIHREQGJFWKJS
MTPJHAEFQZAAULDRCHJCCDYRFVVRIVUYEEGFIVDRCYGURQDREDAKUBNFGUPR
OQYLOBCWQXKZMAUSJGMHCMHGDNMPHNQKAMHURKTRFFACLVGRZKKLDACLLTEO
JOMONXRQYJZGINRNNZWACXXAEDRWUDXZRFUSEWJTBOXVYNFHKSTCENAUMNDD
XFDMVZCAUTDCCKXAAYDZSXTTOBBGQNGVVPJGOJOGLMKXGBFCPYPCKQCHBDDZ
WRXBZMQRLXVOBTWHXGINFGFRCCLMZNMJUGWWBSQFCIHUBSJOLLMSQSGHMCPH
ELSOTFLBGSFNPCUZSRUPCHYNVZHCPQUGRIWNIQXDFJPWPXFBLKPNPEELFJMT'''matrix = m.split('\n')
cnt = 0
for i in range(1,29):for j in range(1,59):if matrix[i][j] < matrix[i-1][j] and matrix[i][j] < matrix[i+1][j] and matrix[i][j] < matrix[i][j+1] and matrix[i][j] < matrix[i][j-1]:cnt += 1
print(cnt)

5. 最小矩阵

问题描述

小蓝有一个 100 行 100 列的矩阵,矩阵的左上角为 1。其它每个位置正好比其左边的数大 2,比其上边的数大 1 。
例如,第 1 行第 2 列为 3,第 2 行第 2 列 为 4,第 10 行第 20 列为 48。

小蓝想在矩阵中找到一个由连续的若干行、连续的若干列组成的子矩阵,使得其和为 2022,请问这个子矩阵中至少包含多少个元素(即子矩阵的行数和列数的乘积)。

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

这道题来说,由于数据不大,所以我们直接暴力即可得到答案

只需要根据规则生成一个100行100列的矩阵,然后不断遍历子矩阵,得到2022即可,暴力解决即可

参考答案

12

m = [[0]*100 for _ in range(100)]
for i in range(100):m[i][0] = i + 1 # 对于第一列来说,肯定是1,2,3,...100,因为第一个数为1,其他比上一行数大1for j in range(1,100):m[i][j] = m[i][j-1]+2 # 其左边的数大 2# 取matrix[a:c][b:d]的子矩阵的和
def sum_matrix(a,b,c,d):ans = 0for i in range(a,c+1):for j in range(b,d+1):ans += m[i][j]return ansres = float('inf') # res初始化为无穷大的数for i in range(100):for j in range(100):for k in range(i,100):for z in range(j,100):ans = sum_matrix(i,j,k,z)if ans == 2022:res = min(res,(k-i+1)*(z-j+1))breakelif ans > 2022:break
print(res)

6. 核酸日期

问题描述

如果周一做核酸,周二显示核酸天数为 1 天,周三显示 2 天,以此类推,周六显示 5 天,周日显示 6 天。
小蓝在某一天做了一次核酸,请问他的核酸显示为几天。已知做核酸和查看核酸不是在同一天,而且相差不超过 6 天(显示的数为 1 到 6 之间的数)。

输入格式

输入第一行包含一个整数 s ,表示小蓝做核酸是周几。 s 为 1 到 6 依次表示周一到周六,s 为 7 表示周日。
第二行包含一个整数 t ,表示查看核酸是周几。 t 为 1 到 6 依次表示周一到周六,t 为 7 表示周日。

输出格式

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

样例输入

5
2

样例输出

4

评测用例规模与约定

对于所有评测用例,1<=s,t<=71<=s,t<=71<=s,t<=7。

思路

其实我的思路很简单,因为相差不超过6天,且不在同一天,这样就很简单了

第一是在同一个星期,只有后-前即可

第二个跨了一个星期,那就当前星期剩余的天数+下个星期过的天数即可

参考代码

s = int(input())
t = int(input())if t > s:print(t-s)
else:print(7-s+t)

7. 英文转换

问题描述

输入一个由小写英文字母组成的字符串,请将其中的元音字母(a, e, i, o, u)转换成大写,其它字母仍然保持小写。

输入格式

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

输出格式

输出转换后的字符串。

样例输入

lanqiao

样例输出

lAnqIAO

评测用例规模与约定

对于所有评测用例,字符串的长度不超过100。

思路

这道题实际上更简单,我们只需要对发现的元音字母全部转化为大写即可,只需要一次遍历,而且规模100,完全足够

参考代码

s = input()
res = ''
for i in s:if i in "aeiou":res += i.upper() # 转化为大写else:res += i
print(res)

8. 充电器

问题描述

小蓝有一个充电器,可以使用不同的电压和电流充电。
给定充电器工作的记录,请计算在这个记录期间总共通过充电传输了多少电能。

输入格式

输入第一行包含一个整数 n , 表示记录的条数。

接下来 n 行,每行包含一个时刻 T 和两个非负整数 U, I,表示在时刻 T 充电电压变为 U(单位伏),电流变为 I(单位A)。最后一行满足 U 和 I 均为 0,在前面的行中也可能出现 U、I 为 0 的情况。其中时间表示为 HH:MM:SS 的格式,时分秒分别用两位十进制数表示(补前导零)。
输入保证时刻依次递增且在 00:00:00 至 23:59:59 的区间内,不用考虑跨过零点充电的情况。

输出格式

输出一个整数,表示总共通电的电能为多少焦耳,其中 1 焦耳等于 1 伏乘以1 安乘以 1 秒。

样例输入

3
12:00:00 12 1
12:01:02 5 2
12:01:10 0 0

样例输出

824

评测用例规模与约定

对于所有评测用例,1<=n<=100,0<=U,I<=1001<=n<=100,0<=U,I<=1001<=n<=100,0<=U,I<=100

思路

这道题其实需要看清楚题目的意思,实际上就是 UIt 的公式,UI简单一点,然后时间差需要获得,而且这道题不考虑跨过0点充电,都集中在一天内,所以问题就简单很多,只需要全部把时间转化为秒数,根据公式求解即可。

参考代码

n = int(input())# 将时间转化为秒数
def get_second(t):h,m,s = map(int,t.split(':')) # 分别得到hour,minute,secondreturn h*3600+m*60+sT = [] # t储存所有的时间
for i in range(n):t,u,v = input().split() # 输入三个值u,v = int(u),int(v)t = get_second(t)T.append((t,u,v))ans = 0
for i in range(n-1):U,I = T[i][1], T[i][2] # 电流和电压t = T[i+1][0] - T[i][0] # 时间差ans += U*I*t # UIt
print(ans)

9. 全相等三角形

问题描述

给定一个字母矩阵,定义一个LQ三角形为某行中连续的几个字母、某列中连续的几个字母和一条45度的斜线中连续的几个字母组成的等腰直角三角形的边缘部分,其中每条边上的字母数量相等且至少为2 。
例如,对于下面的字母矩阵中,所有的字母 L 组成一个LQ三角形,所有字母 Q 组成了一个 LQ 三角形,所有字母 C 也组成了一个 LQ 三角形。

AAAAAAA  
ALLLLLA   
ALQQLAA   
ALQLAAC   
ALLAACC   
ALAACCC

如果一个 LQ 三角形边上的所有字母相等,则称为一个全相等三角形。以三个例子都是全相等三角形。
给定一个字母矩阵,请求其中有多少个全相等三角形。

输入格式

输入第一行包含两个整数 n, m,分别表示字母矩阵的行数和列数。
接下来 n 行,每行 m 个大写字母,为给定的矩阵。

输出格式

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

样例输入1

3 4
AAAA
ALAQ
ALQQ

样例输出1

4

样例输入2

6 7
AAAAAAA
ALLLLLA
ALQQLAA
ALQLAAC
ALLAACC
ALAACCC

样例输出2

23

评测用例规模与约定

对于50%的评测用例,1<=n,m<=101<=n,m<=101<=n,m<=10。

对于所有评测用例,1<=n,m<=1001<=n,m<=1001<=n,m<=100。

思路

对于这道题来说,一开始来看,没有什么思路,似乎想不到有什么其他的算法可以解决,可能用暴力就可以解决,并且似乎评测用例的数据也不大,所以这道题还是暴力解决啦,哈哈哈,

也就是用双层循环遍历每一个元素,把每一个元素作为直角,一共有四种情况,然后符合情况的计数即可,算法复杂度应该在O(n3)O(n^3)O(n3)

参考代码

from re import Ln,m = map(int, input().split())M = []
for _ in range(n):M.append(input())ans = 0 # 计数 LQ三角形# 定义函数,查看是否是LQ三角形,一共有四种
# 因为一共有4个方向,两两相邻的组合,一共是四种情况
def check(x,y,a,b,d):if d == 0:# _|的情况# x,y 为左顶点# a,b 为上顶点while x >= a and y <= b:if M[a][b] != M[x][y]: return Falsex -= 1y += 1elif d == 1:# |_的情况# x,y 为右顶点# a,b 为上顶点while x >= a and y >= b:if M[a][b] != M[x][y]: return Falsex -= 1y -= 1elif d == 2:# -|的情况# x,y 为左顶点# a,b 为下顶点while x <= a and y <= b:if M[a][b] != M[x][y]: return Falsex += 1y += 1elif d == 3:# |-的情况# x,y 为右顶点# a,b 为下顶点while x <= a and y >= b:if M[a][b] != M[x][y]: return Falsex += 1y -= 1return True
for i in range(n):for j in range(m):up,down,left,right = 0,0,0,0# 得到上下左右相等的最大的数,利用四个while循环while (i - up) >= 0 and M[i][j] == M[i-up][j]:up +=1 while (i + down) < n and M[i][j] == M[i+down][j]:down +=1 while (j - left) >= 0 and M[i][j] == M[i][j-left]:left +=1 while (j + right) < m and M[i][j] == M[i][j+right]:right +=1 # _|的情况for k in range(1,min(up,left)):# 左顶点坐标(i,j-k),上顶点坐标(i-k,j)if check(i,j-k,i-k,j,0):ans += 1# |_的情况for k in range(1,min(up,right)):# 右顶点坐标(i,j+k),上顶点坐标(i-k,j)if check(i,j+k,i-k,j,1):ans += 1# -|的情况for k in range(1,min(down,left)):if check(i,j-k,i+k,j,2):ans += 1# |-的情况for k in range(1,min(down,right)):if check(i,j+k,i+k,j,3):ans += 1print(ans)

10. 最小下标

问题描述

小蓝有一个由大写字母 ABCDEF 组成的字符串 S ,长度为 n,字符串的下标依次为 0 到 n-1 。
小蓝按照如下方法生成一个无限长的字符串:
首先选定一个 0 到 n-1 之间的数,作为初始下标。

从初始下标开始,将下标对应的字符加入到字符串的结尾,将字符的序号(A到F依次对应 1 到 6 )与下标相加作为新的下标值,如果下标大于等于 n,将其对 n 求余。重复此过程,即得到无限长的字符串。
例如,对于字符串 ACDF,当初始下标是 0 时,生成的字符串为:ACACACACAC…
再如,对于字符串 DCBA,当初始下标是 1 时,生成的字符串为:CDDDDDDDDD…
给定小蓝的字符串 S,请问当初始下标为多少时,生成的字符串最小。

输入格式

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

输出格式

输出一行,包含一个整数,为所求的下标,如果有多个下标满足要求,输出最小的那个。

样例输入1

DCBA

样例输出1

3

样例输入2

AAAA

样例输出2

0

评测用例规模与约定

令 ∣S∣|S|∣S∣ 表示 SSS 的长度。
对于 30%30 \%30% 的评测用例, 1<=∣S∣<=1001<=|S|<=1001<=∣S∣<=100 。
对于 50%50 \%50% 的评测用例, 1<=∣S∣<=10001<=|S|<=10001<=∣S∣<=1000 。
对于 70%70 \%70% 的评测用例, 1<=∣S∣<=100001<=|S|<=100001<=∣S∣<=10000 。
对于 80%80 \%80% 的评测用例, 1<=∣S∣<=1000001<=|S|<=1000001<=∣S∣<=100000 。
对于所有评测用例, 1<=∣S∣<=10000001<=|S|<=10000001<=∣S∣<=1000000 。

思路

这道题的话,我一开始看的时候,实际上脑子里面没有想到什么好的方法去解决,但是可以知道的是,我们用暴力应该是可以过一部分的分的,因为暴力的话,大约是O(n2)O(n^2)O(n2)的算法,只要每个遍历一遍,大概判断一下是否更小即可,并且在中间,如果遇到已经比最小的大了的字符,就直接break,这样就可以减轻一部分的计算量,类似于比如已经计算了A开头的循环字符串,Z开头的一开始就已经比A大了,所以他可以直接被pass掉,这样就可以暴力拿到一部分的分。


当然,这肯定不是最优解,感觉那样的方法,应该拿50%+的分左右,但是肯定不是拿满分的标程

通过大佬的博客https://blog.csdn.net/m0_46326495/article/details/127720544的讲解,我明白了这道题实际上是利用最小表示法求解的。即把原最小表示法的向后移动i,ji,ji,j指针的操作改成了使用getNextgetNextgetNext函数获取下一个下标,这样就成了循环找我们的下标,并借助visvisvis标记访问过的下标,最后时间复杂度为O(n)O(n)O(n)

如果不懂最小表示法,可以上网搜一下最小表示法是什么,或者参考https://oi-wiki.org/string/minimal-string/

参考代码

暴力法

S = input()
n = len(S) # 输入字符串的长度# 获得下标为i的下一个下标
# 根据题目描述写出此函数
def getNext(i):return (i + ord(S[i]) - ord('A') + 1)%nans = 0
min_s = 'Z'*n
for i in range(n):s = S[i]x = iwhile len(s) < n: # 最多循环n次,相当于每个整个字符串循环一遍next_i = getNext(x)s += S[next_i]x = next_iif s > min_s: # 如果前面已经遇见了大于已有的时候,直接breakbreakif s < min_s:min_s = s # 得到新的最小字符串ans = i # 得到最小下标
print(ans)

最小表示法

S = input()
n = len(S) # 输入字符串的长度# 获得下标为i的下一个下标
# 根据题目描述写出此函数
def getNext(i):return (i + ord(S[i]) - ord('A') + 1)%nvis = [0]*(n+1)
vis[0] = True
vis[1] = True
# 最小表示法
k, i, j = 0, 0, 1 # i为初始下标0, j为初始下标1
ii,jj = 0,1
while k < n and i < n and j < n:if S[ii] == S[jj]:ii = getNext(ii) # 找到下一个下标jj = getNext(jj)k += 1 # 长度+1else:if S[ii] > S[jj]:temp = iwhile temp != ii:vis[temp] = Truetemp = getNext(temp)while vis[i]: # 已经标记过i += 1 # 类似于最小表示法中有相同字符的vis[i] = True # 标记else:temp = jwhile temp != jj:vis[temp] = Truetemp = getNext(temp)while vis[j]: # 已经标记过j += 1 # 类似于最小表示法中有相同字符的vis[j] = True # 标记ii,jj = i,j # 重新定义初始下标,继续比较k = 0
ans = min(i, j)
print(ans)

第十四届蓝桥杯第一期模拟赛 python相关推荐

  1. 第十四届蓝桥杯第一期模拟赛试题与题解 C++

    第十四届蓝桥杯第一期模拟赛试题与题解 C++ 试题 A 题解:位运算 试题 B 题解:日历模拟 试题 C 题解:double 求和 试题 D 题解:枚举 试题 E 题解:二维前缀和 试题 F 题解:两 ...

  2. 第十四届蓝桥杯第二期模拟赛 【python】

    第十四届蓝桥杯第二期模拟赛 [python] 文章目录 第十四届蓝桥杯第二期模拟赛 [python] ✨最小的2022 (python二进制) ❓️问题描述 答案提交

  3. 第十四届蓝桥杯第三期模拟赛 C/C++ B组 原题与详解

    本篇文章对第十四届蓝桥杯第三期模拟赛所有的题目进行了详细解析.如果大家还想刷题的话,我给大家整理出了第十二届的省赛真题:第十二届省赛C/C++ B组真题.推荐大家可以去做一下. 文章目录 一.填空题 ...

  4. 【第十四届蓝桥杯单片机组模拟赛1】

    第十四届蓝桥杯单片机组模拟赛1 距第十四届蓝桥杯单片机还有不到一个月的时间啦,加油 源码 /*------------------------------第十四届蓝桥杯单片机模式赛---------- ...

  5. 十四届蓝桥青少组模拟赛Python-20221108

    十四届蓝桥青少组模拟赛Python-20221108 T1.二进制位数 十进制整数2在十进制中是1位数,在二进制中对应10,是2位数. 十进制整数22在十进制中是2位数,在二进制中对应10110,是5 ...

  6. 第十四届蓝桥杯cb组省赛个人题解

    试题 C: 冶炼金属 ​ 时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分 [问题描述] ​ 小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X.这个 炉子有一个称作 ...

  7. 第十四届蓝桥杯软件类省赛备赛分享帖(Web应用开发组)

    文章目录

  8. 十四届蓝桥青少组省赛Python中高级选拔赛——20221030

    考试中心22年10月30日Python中高级在线考试 T1. 单选题 执行print(5%3)语句后,输出的结果是(C) A. 0 B. 1 C. 2 D. 3 T2. 单选题 以下选项中,哪一个是乘 ...

  9. 2022 第十四届蓝桥杯模拟赛第一期(题解与标程)

    第十四届蓝桥杯模拟赛第一期 1. 二进制位数 问题描述 答案提交 参考答案 2. 晨跑 问题描述 答案提交 参考答案 3. 调和级数 问题描述 答案提交 参考答案 程序验证 4. 山谷 问题描述 答案 ...

最新文章

  1. 深js, jsconf China 回顾
  2. 社工库网址与制作方法
  3. 如何正确实现 Java 中的 HashCode
  4. 从Http的连接到WebSocket
  5. 用C语言实现字符串的右旋
  6. 你的手机浏览器不支持webgle_中国联通回应“逐渐关闭2G、3G网络”:系用户手机不支持...
  7. python中if brthon环境安装包_python-debian/test.deb.uu at master · romlok/python-debian · GitHub...
  8. adc matlab代码,pudn-几种ADC设计的matlab源码
  9. Java使用comms-net jar包完成ftp文件上传进度的检测功能
  10. Oracle的SQL注入
  11. linux系统下 usb网卡的驱动安装
  12. 计算机数值方法知识,计算机数值方法.pdf
  13. cmd md命令 创建文件夹
  14. python 投掷骰子实验
  15. 海康威视2021年营收814亿:增长28% 净利168亿
  16. Day 13 JUSTICE
  17. ITK05 孔洞填充
  18. 需求用户app的主题颜色能根据手机壳的颜色自动调整
  19. 在linux中运行电子词典,《Linux下电子词典的设计和实现》.doc
  20. frozen ui php,手机版开发框架集合 Frozen UI WeUI SUI Mobile

热门文章

  1. PHP分布式路由算法介绍与实现
  2. 求1-100的和的几种方法
  3. 论文写作相关事项汇总
  4. java 登录界面加验证码_java 做登陆窗口,带有用户名和密码输入框和验证码。求修改...
  5. 识别PDF关键词,在文件页数和坐标
  6. Linux压缩命令gzip, bzip2和tar
  7. android之父:安迪*鲁宾
  8. html在字体两边加直线,css怎么在文字两边加上横线
  9. flask框架学习笔记
  10. 几个巧妙的电流检测电路