【蓝桥杯 2023】省赛 PA

坐标陕西省,刚出成绩,拿了省二,学习了不到三个月。可以说还是很适合我这种小菜鸡打的比赛,分享一下比赛的思路,代码质量都比较低,大佬见谅。

题目:

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....但是在学习的过程中帮助了课程学习,不管怎么想都是不亏的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值