全网最详细蓝桥杯真题+代码+解析,绝对通俗易懂,一点就通!
专治各种没资源,没思路,没代码等新手入门级BUG。
在文章结尾可免费领取蓝桥杯真题PDF。
全文目录
试题A:卡片
1 真题
2 解析
3 代码
试题B:直线
1 真题?
2 解析
3 代码
试题C:货物摆放
1 真题
2 解析
3 代码
试题D:路径
1 真题?
2 解析
3 代码
试题A:卡片
1 真题
2 解析
难度系数:?
考察题型:枚举?
涉及知识点:?字符串:str()? 计数方法:.count()
思路分析:
第一题就这么暴力,不愧是BF杯。循环就完事了!
经过一波分析,从材料中“拼11时卡片1已经只有一张了”推理出卡片1最先
原因是0到9十张卡片,从1开始拼,1最先使用,也就意味着1最先用光。
然后得出思路:先循环遍历可以拼出的数字,再将整数格式转换成字符串格式,
为的是调用count()方法,来统计"1"出现的次数,
那么当"1"出现了2021次时,题目就被KO了!
3 代码
#卡片
count=0 #计数器:统计1的个数
i=1 #从1开始遍历
while True: #循环次数未知,用while循环
count+=str(i).count("1") #.count("1")方法:统计i中"1"出现的次数
if count==2021: #如果"1"出现2021次,说明这次循环中卡片1刚好用完
print(i) #打印输出结果:3181
break
i+=1
试题B:直线
1 真题
2 解析
难度系数:?
考察题型:枚举? 数论
涉及知识点:?集合docker=set()? 斜率截距公式(k,b)
思路分析:
一条普普通通的直线,竟然能变出这么多花样?直线,接招!( ?? ω ?? )?
首先创建二维列表存放坐标系,然后二重循环遍历,给每个坐标点赋初值。
因为要统计不同的直线,所以用直线的性质:斜率和截距 来区分,并存放到集合容器里,
最后一点小细节,当斜率不存在时,k会报错,
所以单独计算,最后直接加上20条垂直x轴的直线。
3 代码
#直线
points=[[x,y] for x in range(20) for y in range(21)] #创建二维列表:代表xy坐标系
docker=set() #创建集合属性的容器:因为集合里的元素不会重复
for i in points: #二重循环遍历每个坐标
x1,y1=i[0],i[1] #注意书写格式:a,b=c,d
for j in points:
x2,y2=j[0],j[1]
if x1==x2: #特殊情况:直线垂直时斜率不存在,先跳过最后计算
continue
k=(y2-y1)/(x2-x1) #斜率公式
b=(x2*y1-x1*y2)/(x2-x1) #截距公式
if (k,b) not in docker: #存入容器里没有的(斜率,截距)对
docker.add((k,b))
print(len(docker)+20) #输出结果:容器的长度40237+斜率不存在的20种情况=40257
试题C:货物摆放
1 真题
2 解析
难度系数:??
考察题型:枚举 数论
涉及知识点:?约数 集合
思路分析:
长宽高,三重循环,枚举暴力,yyds!(′▽`???)
两个知识点:一个是约数,另一个是集合。
1、判断约数算法: n%i==0
约数指的是被整除后没有余数的数。
举个栗子:3%1==0? 3%3==0? 1和3就是3的约数。
2、创建集合容器方法:docker=set()
选用集合作为容器存放数据,是因为集合的数据不会重复。相同的数据不会重复添加。
3 代码
n=2021041820210418 #货物数量
cnt=0 #统计值赋初始值0
docker=set() #创建集合属性的容器
for i in range(1,int(n**0.5)+1): #循环遍历,筛选n的约数(对n开根号的写法是为了加快速度)
if n%i==0: #如果可被整除,判断为约数
docker.add(i) #添加约数
docker.add(n//i)
for i in docker: #三重循环遍历容器(三重循环快到运行5s出结果)
for j in docker:
for k in docker:
if i*j*k==n: #满足条件,方案数+1
cnt+=1
print(cnt) #输出结果:2430
试题D:路径
1 真题
2 解析
难度系数:??
考察题型:数论 ?动态规划
涉及知识点:最小公倍数 最短路径?
思路分析:
这道题可谓是究极嵌套!融合了最短路径,最小公倍数和动态规划。一个不会就全凉了~
最小公倍数我已经整理成精简模板放代码里了,考试时直接套模板就行。
动态规划经典的做题步骤有5步。
?第一步:明白dp[i]的含义
dp[i] #i:结点编号1~2021 #dp[i]:当前结点到结点1的最短路径长度
第二步:给dp数组初始化赋值
dp=[float('inf')]*(n+1) #创建列表赋值为无穷大
dp[1]=0 #结点1的长度初始化为0
第三步:弄清dp[i]遍历的顺序
for i in range(1,n+1): #先遍历结点a:遍历结点1~n
for j in range(i+1,i+22): #再遍历结点b:遍历结点i+1~i+21
第四步:搞懂递推公式
dp[j]=min(dp[j],dp[i]+lcm(i,j)) #递推公式
第五步:打印数组
print(dp[n]) #输出结果:10266837
参考资料:
python的动态规划我是看这个视频学的,学会里面的经典案例,动态规划一通百通~
清华计算机博士带你学习Python算法+数据结构_哔哩哔哩_bilibili
3 代码
#最小公倍数模板(least common multiple)
def lcm(a,b):
if a<b:
a,b=b,a
c,d=a,b
while d!=0:
c,d=d,c%d
return (a*b)//c
#最短路径(dp)
n=2021 #结点数量
dp=[float('inf')]*(n+1) #创建列表赋值为无穷大
dp[1]=0 #结点1的长度初始化为0
for i in range(1,n+1): #结点a:遍历结点1~n
for j in range(i+1,i+22): #结点b:遍历结点i+1~i+21
if j>n: #j超出结点范围时
break #结束循环
dp[j]=min(dp[j],dp[i]+lcm(i,j))#递推公式
print(dp[n]) #输出结果:10266837
PDF百度云下载链接:
第十二届蓝桥杯大赛软件赛省赛 Python 大学 A 组
提取码:6666
如果文章对你有帮助,记得点赞👍+关注💡+收藏?
思路君持续为你提供高质量题解!💪🏻一起Fighting!
|