坐标陕西省,刚出成绩,拿了省二,学习了不到三个月。可以说还是很适合我这种小菜鸡打的比赛,分享一下比赛的思路,代码质量都比较低,大佬见谅。
题目:
2023年第十四届蓝桥杯大赛软件类省赛Python大学A组真题 - 题库 - C语言网 (dotcpp.com)
- 试题 A: 特殊日期
- 试题 B: 分糖果
- 试题 C: 三国游戏
- 试题 D: 平均
- 试题 E: 翻转
- 试题 F: 子矩阵
- 试题 G: 阶乘的和
- 试题 H: 奇怪的数
- 试题 I: 子树的大小
- 试题 J: 反异或 01 串
感觉巨简单,直接暴力,结果后面发现闰年的判断有误。
res = 0
for yy in range(2000,2000000):
for mm in range(1,12+1):
flag = (yy%4==0 and yy%100!=0) or yy%400==0
if mm==1 or mm==3 or mm==5 or mm==7 or mm==8 or mm==10 or mm==12:
for dd in range(1,31+1):
if yy%mm==0 and yy%dd==0:
res+=1
if mm==4 or mm==6 or mm==9 or mm==11:
for dd in range(1,30+1):
if yy%mm==0 and yy%dd==0:
res+=1
if mm==2 and flag:
for dd in range(1,28+1):
if yy%mm==0 and yy%dd==0:
res+=1
else:
for dd in range(1,29+1):
if yy%mm==0 and yy%dd==0:
res+=1
print(res)
后面修改了一下,不知道答案对不对,跑出来时间也不算很久。
65481122
没做出来
C题:
题目来源:P2089 - [蓝桥杯2023初赛] 三国游戏 - New Online Judge (ecustacm.cn)
考试的时候没做出来,后面想想其实是一个深度搜索,不过得处理好标记。最后写了一个特殊情况上去,估计没捞到分数。
n = int(input())
arr = [list(map(int,input().split(" "))) for i in range(n)]
print(-1)
D题:
题目来源:P2104 - [蓝桥杯2023初赛] 平均 - New Online Judge (ecustacm.cn)
是个比较基础的题目了,主要就是排序啦,要是想优化可以利用优先队列取出溢出的前几个最小的。不过比赛的时候懒得尝试,赶时间,直接sort了。估计还是水到了一点分数。
n = int(input())
arr = [list(map(int,input().split(" "))) for i in range(n)]
cot = [0 for i in range(10)]
pri = [[] for i in range(10)]
for i in range(n):
a,b = arr[i][0],arr[i][1]
cot[a] += 1
pri[a].append(b)
for i in range(n):
pri[a].sort()
aver = n//10
res = 0
for i in range(n):
if cot[i]>aver:
t = cot[i]-aver
res += sum(pri[i][0:t:1])
print(res)
E题:
题目来源:P2091 - [蓝桥杯2023初赛] 翻转 - New Online Judge (ecustacm.cn)
就是个模拟,考虑清楚应该还行。
n = int(input())
arr = []
res = []
for i in range(n):
t =[]
t.append(input().strip())
t.append(input().strip())
arr.append(t)
for i in range(n):
s1,s2 = arr[i][0],arr[i][1]
ver = [0]*len(s1)
for j in range(len(s1)):
if s1[j]!=s2[j]:
ver[j]=1
r = 0
flag = True
for j in range(len(s1)):
if ver[j]==1:
if j==0 or j==len(s1)-1:
res.append(-1)
flag = False
break
else:
if ver[j-1]==0 and ver[j+1]==0:
r += 1
else:
res.append(-1)
flag = False
break
if flag:
res.append(r)
#print(res)
for i in res:
print(i)
F题;
题目来源:P2092 - [蓝桥杯2023初赛] 子矩阵 - New Online Judge (ecustacm.cn)
一眼数据量就觉得是dp,不过没想出来,直接暴力了,可能能过了10%左右。
n,m,a,b = map(int,input().split(" "))
arr = [list(map(int,input().split(" "))) for i in range(n)]
mod = 998244353
res = 0
for i in range(0,n-a+1):
for j in range(0,m-b+1):
m = arr[i][j]
M = arr[i][j]
for x in range(i,a+i):
for y in range(j,b+j):
m = min(m,arr[x][y])
M = max(M,arr[x][y])
res = (res+m*M)%mod
print(res)
G题:
题目来源:蓝桥杯2023年第十四届省赛真题-阶乘的和 - C语言网 (dotcpp.com)
这种题目一看就是数学题目了,暴力想都别想,直接归纳各种情况就好了,考试能归纳出越多情况对的概率越大。
n = int(input())
arr = list(map(int,input().split(" ")))
sc = max(arr)
cot = [0]*(sc+1)
for i in range(n):
cot[arr[i]] += 1
for i in range(sc-1,0,-1):
cot[i] = cot[i]+cot[i+1]
m = 1
while True:
if m<=sc and cot[m]==n:
cot[m]=0
m += 1
else:
break
m-=1
if m+1<n:
print(m)
else:
flag=False
for i in range(m,sc):
if cot[i]!=0:
flag =True
braek
if flag:
print(m)
else:
if m+1 == n:
print(m+1)
H题:
题目来源:蓝桥杯2023年第十四届省赛真题-奇怪的数 - C语言网 (dotcpp.com)
这种题目先把极端情况考虑进去,然后再思考一般情况。我先考虑了取不到的情况和全能取得情况,剩下得情况使用dp解决,不过后面发现我的dp转移方程有问题,后面模拟发现确实只有几种情况我的dp能用。 不过还是可以了。
n,m = map(int,input().split(" "))
mod = 998244353
if m>=45:
res = 1
for i in range(n):
res = (res*5)%mod
print(res)
elif m<3:
print(0)
else:
ji = [1,3,5,7,9]
ou = [0,2,4,6,8]
ini = 0
for x1 in ji:
for x2 in ou:
for x3 in ji:
for x4 in ou:
for x5 in ji:
if (x1+x2+x3+x4+x5)<=m:
ini+=1
dp = [0]*(n+1)
dp[5] = ini
for i in range(6,n+1):
if i%2==0:
dp[i] = (dp[i-1]*15)%mod
else:
dp[i] = (dp[i-1]*10)%mod
res = dp[n]
if n%2==0:
res = (res-5*dp[n-1])%mod
print(res)
I题:
题目来源:蓝桥杯2023年第十四届省赛真题-子树的大小 - C语言网 (dotcpp.com)
不会,真的不会,花了巨久时间,因为一开始看到完全k叉树以为套个堆或者线段树的模板就能写出来,结果不仅时间搭进去了,也没做出来,甚至不如花点时间想想暴力。
J题:
题目来源:蓝桥杯2023年第十四届省赛真题-反异或 01 串 - C语言网 (dotcpp.com)
给我感觉就像模拟,然后想了一会发现反异或串操作不知道怎么模拟出来。就开始思考规律,试了一会,发现一点规律,现在看来只是对了一小部分,不过也有分了。
s = input().strip()
n = len(s)
arr = []
for i in range(len(s)):
arr.append(int(s[i]))
pre = sum(arr)-1
#print(arr)
def f():
# 找到最大对称串
r = ''
for i in range(0,n):
for j in range(n,i,-1):
sub = s[i:j]
res = sub[::-1]
flag = (sub==res) and ('1' in sub) and sub[0]!='0' and sub[-1]!='0'
if flag:
if len(sub)>=len(r):
r = sub
num_0 = 0
num_1 = 0
for i in range(len(r)):
if r[i]=='0':
num_0+=1
else:
num_1+=1
save = num_1//2-num_0
return save
save = f()
print(pre-save)
等网上标准答案出来了,我再好好复盘。
做个小总结:
首先,蓝桥杯确实适合新手打,不过还是要有些基础吧。只会暴力的话还是挺难受的,比如我已经学完了数据结构,虽然我的代码中基本是暴力算法,但是有些题目还是包含了不少数据结构知识和一些小算法的。可以说比赛和自己平时练习差距还是很大的,自己练习可以好好想,比赛一紧张就想暴力了,但是如果学过一些算法,写暴力的时候也可以优化甚至写出好的算法。
其次,我报名蓝桥杯纯纯是为了德育分,比赛准备不算非常认真,刷了不到50道题目,其中还有不少水题。所以如果学校能报销,大家可以踊跃报名尝试的。
最后,其实虽然我学了很多好的算法和数据结构都没用上,比如线段树,堆,dp,dfs....但是在学习的过程中帮助了课程学习,不管怎么想都是不亏的。