导航菜单
首页 >  蓝桥杯b组真题python  > 第十一届蓝桥杯软件类Python组(最新)(试题回忆+部分个人解答)

第十一届蓝桥杯软件类Python组(最新)(试题回忆+部分个人解答)

第二次参加蓝桥杯竞赛了,欢迎各位同学来一起交流~ 如果发现我的代码有什么问题的话,敬请指正(抱拳

PS:只记得每个题目的问题本质了,题目原文是怎么描述已经忘得差不多了。

第一题. 贴门牌号

原问题:从1到2020中这些数字中有多少个2(注意:不是问多少个数字里有2),

解题思路:基础题不赘述了哈,好像去年C++组的第一题也是这个呢,不过用Python写可真香

参考代码:

ans = 0for i in range(1,2021):ans += (str(i).count('2'))print(ans)

运行结果是624

第二题. 2020

原问题:在一个给定的由数字 '0' 和 '2' 组成的矩阵中寻找横向往右、纵向往下和斜向往右下的 '2020' 排列,原题中给定的矩阵是300行300列的,在一个txt文件中存放。

解题思路:同样数据量不大,暴力就完事了,考试时我还不知道怎么用python读取txt,只能在控制台手动输入,最后一行输入一个1作为结束标志。

参考代码:

def check(s):return s == '2020'matrix = []s = input()while '1' not in s:matrix.append(list(s))s = input()n,m = len(matrix),len(matrix[0])ans = 0for i in range(n):for j in range(m):if i + 3 < n and check(matri[i][j] + matrix[i+1][j] + matrix[i+2][j] + matrix[i+3][j]):ans += 1if j + 3 < m and check(matrix[i][j:j+4]):ans += 1if i + 3 < n and j + 3 < m and check(matri[i][j] + matrix[i+1][j+1] + matrix[i+2][j+2] + matrix[i+3][j+3]):ans += 1print(ans)

当时的结果好像是16520。。。记不太清了

第三题. 跑步

原问题:小明坚持每天跑步,正常情况下每天跑一公里,如果这一天是周一或者月初(每月的一号),那么小明就会跑两公里(如果这一天既是周一,又是月初,小明也是跑两公里),小明从2000年1月1日(周六)一直坚持到了2020年10月1日(周四),请你计算一下小明共跑了多少公里?

解题思路:就是统计2000年1月1日到2020年10月1日(包含)以来共有多少天是周一或者月初,考试的时候绞尽脑汁写得代码,结果还错了,事后看别人题解才知道还有datetime库这个东西,我哭了。

参考代码(事后诸葛亮):

from datetime import *start = date(2000,1,1)end = date(2020,10,2)tmp = timedelta(days = 1)ans = 0while start != end:if start.weekday() == 0 or start.day == 1:ans += 2else:ans += 1start = start + tmpprint(ans)

运行结果为8879

第四题. 蛇形排列 

问题分析:在蛇形排列矩阵中,第20行第20列的数字是多少?蛇形排列方式如图所示:

蛇形排列

 

解题思路:在该数字的左上方有 19+19 = 38 个斜排,最后一个数是 38 * (38+1) / 2 = 741,741 + 20 = 761,如图所示:

如果非得编程求解的话:那就定义两种遍历模式,一种是有↗方向,一种是↙方向,判断行号加上列号的和是单数还是偶数,

参考代码:

i = 0j = 0num = 0while True:num += 1if i == 19 and j == 19:breakif (i+j)&1:i += 1if j > 0:j -= 1else:j += 1if i > 0:i -= 1print(num)

运行结果是761

第五题. 冒泡排序

原问题:对一个字符串,对它进行冒泡排序使其为升序,例如:对于lan,排序成 aln 需要交换一次(只能交换相邻的两个字母),对于qiao,排序成 aioq 就需要交换4次。请找出冒泡排序时恰好需要交换100次的字符串,如果有多个字符串满足条件,则找出最短的那个,如果有多个满足条件而且还是最短的,则找出字典序最小的那个。

问题分析:长度为 n 的降序数组的冒泡排序交换次数是 (n-1) * n / 2 次,大于等于100的第一个数是 105 = (15-1) * 15 / 2,所以最短的长度肯定是15了,再考虑到字典序最小,则答案应该就是onmlkjihgfedcba排列而成的,字典序最小,就需要第一个字母的字典序尽可能小,然后才是第二个、第三个……,那么就把正数第六个字母提到前面,结果应该就是jonmlkihgfedcba(当时推出来以后没有拿程序验证一下 ,心里还是很没底的)

参考验证代码:

def bubble_sort(arr):num = 0for i in range(len(arr)-1,0,-1):for j in range(i):if arr[j] > arr[j+1]:num += 1arr[j],arr[j+1] = arr[j+1],arr[j]return numprint(bubble_sort(list('jonmlkihgfedcba')))

运行结果是100

第六题到第十题就是编程题了,第六题第七题很基础,第八题开始就有难度了,

第六题. 成绩统计

问题:给定 n 个学生的成绩,大于等于60的为及格,大于等于85的为优秀。请你统计这 n 名同学的及格率和优秀率。

输入格式:第一行一个数n,表示接下来有n行数据,接下来n行每行一个数m,代表该学生的成绩。

输出格式:两行,第一行一个数表示及格率,第二行一个数表示优秀率,都要求四舍五入。

问题分析:该怎么算就不解释了哈,有点说道的地方就是后面的四舍五入和格式化输出了。

参考代码:

n = int(input())num1 = 0num2 = 0for _ in range(n):score = int(input())if score >= 60:num1 += 1if score >= 85:num2 += 1print(str(round(num1*100/n))+'%')print(str(round(num2*100/n))+'%')  第七题. 单词分析

原问题:在给定的字符串中,计算出现次数最多的字母和它的出现次数,如果出现次数最多的字母同时有多个,则找出字典序最小的。

输入格式:一行,代表所要统计的字符串

输出格式:两行,第一行一个字符,是出现最多的字母,第二行一个整数,该字母的出现次数。

解题思路:开一个哈希表统计出现次数就好了。然后从前开始遍历来保证找出的字母的字典序是最小的。

参考代码:

cnt = [0]*26s = input()for alpha in s:cnt[ord(alpha) - ord('a')] += 1k = 0for i in range(26):if cnt[i] > cnt[k]:k = iprint(chr(k+ord('a')))print(cnt[k])第八题. 数字三角形

原问题:在如下图所示的数字三角形中,我们需要从三角形顶部走到底部,在每一个数字处,我们可以选择向临近的右下或者临近的左下走,所经过的数字的总和称为路径和,请你计算从顶部到底部所有路线中最大的路径和为多少?同时要求这条路径选左下的次数和选右下的次数相差不能大于1。

数字三角形

输入格式:第一行一个整数 n ,代表数字三角形的阶数,接下来 n 行中,第 j 行有 j 个整数,代表数字三角形中的第 j 层,整数之间用空格分割。

输出格式:一个整数,代表最大的路径和。

输入样例:

6

1

2 3

7 5 6

4 3 2 3

5 6 5 7 4

7 8 9 6 10 9

输出样例:

29

解题思路:是一个比较原型的动态规划问题,一层一层向下,注意最后输出时要选最后一行的中间两个或者一个。规划过程如下图所示:

规划过程路径和

参考代码:

n = int(input())matrix = [[0]*( _ + 1 ) for _ in range(n)]for i in range(n):tmp = [int(a) for a in input().split(' ')]matrix[i] = tmpdp = matrix[:]for i in range(1,n):for j in range(i+1):if j == 0:dp[i][j] += dp[i-1][j]elif j == i:dp[i][j] += dp[i-1][j-1]else:dp[i][j] += max(dp[i-1][j],dp[i-1][j-1])if n&1:print(dp[n-1][n//2])else:print(max(dp[n-1][n//2-1],dp[n-1][n//2]))第九题. 平面划分

问题:给出N条直线的斜率和截距,计算这些直线会将xy平面划分为多少个区域。

如图中所示,这些直线将平面划分为了7个区域。

输入格式:第一行一个数 n 代表直线的个数,接下来 n 行每行两个整数,分别代表斜率和截距。

输出格式:一行一个整数,代表划分区域的个数。

输入样例:

3

1 1

2 2

3 3

输出样例:

6

解题思路:把这些直线一条一条的加入平面来进行分析,计算当前新加入的直线与之前已加入的直线集合会产生多少个交点,如果产生了k个交点,则划分的区域就会增加 k+1 个(见图所示),在计算交点的时候,需要去重,k个交点的去重时间复杂度大致为O(k*logk),共有N条直线,所以整体时间复杂度为O(N*N*logN),(题目中给出N最大为1000,只能保佑不超时了

参考代码:

n = int(input())line = []for _ in range(n):tmp = [int(a) for a in input().split(' ')]line.append(tuple(tmp))line = list(set(line)) #去重n = len(line)judge = lambda pos1,pos2 : abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1]) < 1e-12 #判断两个点是否为同一个点ans = 2for i in range(1,n):k1,b1 = line[i]sec = []for j in range(i):k2,b2 = line[j]if k2 == k1: continuepos_x = (b2-b1)/(k1-k2); pos_y = k1*pos_x + b1 #计算交点的坐标sec.append((pos_x,pos_y))m = len(sec)tmpans = m+1#交点的数量小于等于1if m < 2:ans += tmpanscontinue#交点的数量大于等于2,需要去重处理sec = sorted(sec,key=lambda x:x[0]) #对交点集合按x轴进行排列for i in range(1,m):if judge(sec[i-1],sec[i]):tmpans -= 1 #有重复的,产生的区域数就减一ans += tmpansprint(ans)第十题. (标题忘了)

(以下题干是我根据自己的理解写的,官方的题干一堆变量名,当时看了有15分钟才明白是啥意思)

问题:在怪物猎人游戏中,玩家可以通过在装备上镶嵌宝珠来获得收益,一共有六件装备,每件装备上都有一定数量的镶嵌孔,每个镶嵌孔都有各自的等级,而宝珠也有等级,镶嵌孔只能镶嵌比自己等级低的宝珠。关于宝珠的说明,宝珠有系列划分,同系列的宝珠没有区别,每个系列的宝珠镶嵌到一定数量时,都会获得一定的收益,如下面举例:

A系宝珠等级是1级,镶嵌数量是 1,2,3,4,5 时,获得的收益分别是 1,2,3,6,7。镶嵌数量超过5个时,收益仍然为7,镶嵌数量上限为5。

B系宝珠等级是2级,镶嵌数量是 1,2,3,4 时,获得的收益分别是 2,5,8,15。镶嵌数量超过4个时,收益仍然为15。镶嵌数量上限为4,以下同理

C系宝珠等级是2级,镶嵌数量是 1,2,3,4 时,获得的收益分别是 4,7,9,13。

D系宝珠等级是3级,镶嵌数量是 1,2,3,4 时,获得的收益分别是 5,10,14,21。

可以看到,你在每个系列上的收益只与你在这个系列上花费的镶嵌孔数量有关,例如对A系宝珠而言,镶嵌3颗时,单位镶嵌孔收益为3/3 = 1,镶嵌4颗时,单位收益为6/4 = 1.5,镶嵌5颗时,单位收益为7/5 = 1.4。等级越高的宝珠系列 单位收益越高(通常而言是这样),而同等级的宝珠系列(例如B系和C系)的单位收益则显得不相上下。现在需要你找出一套镶嵌方案使总收益最大,只输出这个最大收益值即可。

输入格式:前六行代表装备上的镶嵌孔,每行第一个数代表当前装备的镶嵌孔数量,后面的数依次为镶嵌孔的等级。第七行一个整数n,代表有n个系列宝珠,接下来n行,每行代表一个系列,每行的第一个数代表当前系列宝珠的等级,第二个数代表镶嵌数量上限,接下来几个数从低到高依次代表可达到的收益。

数据限制:镶嵌孔和宝珠的等级L不超过4,每个系列的镶嵌数量上限不超过7,系列的数量不超过10000,镶嵌孔的总数不超过300。

输出格式:一个整数,代表最大收益。

输入样例:

1 1

1 1

2 1 2

2 2 1

1 2

1 3

3

1 5 1 2 3 5 8

2 4 2 5 8 15

3 4 5 10 15 21

输出样例:

20

说明:上例共有4个1级镶嵌孔,3个2级镶嵌孔,1个3级镶嵌孔。A, B, C 三个系列的宝珠,镶嵌方案为

(A)(A)(A)(A)(B)(B)(B)(B)

所以最大总收益为 5+15 = 20

 

解题思路:(我太菜了 想不出来,有时间再更

读题就读了半天,暴力枚举应该可以过前几个测试点,感觉有点像背包问题的意思,比赛快结束的时候码了20分钟才发现思路不对,我还是太菜了,(还不如回去检查一下,这样就能把第二题改过来了)

 

码字不易,如果您觉得有所帮助,麻烦在下面点个赞吧 ~

相关推荐: