第十三届蓝桥杯大学A组题解(Python)

写在前面 :

KS感觉这次比赛....Emmm一言难尽,贴吧充斥着车队,B站传着退费视频...

Whatever , 既然报了名并且用心准备了,那就全力以赴👊

本次考试特点 :模拟模拟模拟!从头模到尾!

学了那么久的暴力算法居然只能被冷藏...

———————————————————————————————————————————

* 这次的战果是1道填空 + 7道大题 本篇博客中大题的代码都通过了样例 并不能保证AC

* 如果我任何表达不清或者有任何不理解之处 可以留言交流 我会在看到的第一时间做出回答!

* 如有错误 欢迎指出!

Start :

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

第一题 : 没啥好说的了.. 签到题实锤 注意不要想去怎样写代码 这题纯纯的手算题 初中数学

答案 : 443

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 这道题KS并没有写出来 除了暴力求解 我也确实没想到什么好的算法(我是fw

微信群有一哥们直接写了考试日期 :2022040920220409 据说是正确答案 😂

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 思路:先用素数筛筛出小于n的所有素数 再判断是否能被n整除

n = int(input())

Flag = [True for i in range(n+1)]
for i in range(2,int(n**(0.5))+1) : # 素数筛
    if Flag[i] :
        tmp = i+i
        while tmp < n+1 :
            Flag[tmp] = False
            tmp += i
Sum = 0
for i in range(2,n+1) : # 判断因数
    if n % i == 0 and Flag[i] :
        Sum += 1
print(Sum)

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

我着实没想到第二个大题就让我无从下手...

如果有哪位大佬写出来了或者有思路 欢迎私信我或者在留言区教一下KS...

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 这道题目还是有点意思 一眼看上去很难 但其实只要我们对两个样例模拟一下操作过程 很容易想到解决办法 (实在不行直接打印EMPTY估计也能骗几个测试点

思路:用一个while循环 出循环的条件是:要么字符串为空 要么这轮循环得到的字符串与上一轮循环得到的字符串相同 即后续的操作已经不能再影响字符串了 所以2^64就是吓人用的..

Convert函数:用于转换字符串 模拟裁切边缘字符的过程 我们判断每两个相邻的字符 若满足边缘字符的定义则取出他们的index放入备用集合中 最后返回对应索引不在集合里的字符组成的新字符串


s = input()
def convert(string) :
    res = []
    tmp = set()
    string = list(string)
    for i in range(len(string)) :
        if i == 0 or i == len(string)-1 :
            continue
        else :
            if string[i] == string[i-1] and string[i] != string[i+1] :
                tmp.add(i)
                tmp.add(i+1)
            if string[i] != string[i-1] and string[i] == string[i+1] :
                tmp.add(i-1)
                tmp.add(i)
    
    for i in range(len(string)) :
        if i not in tmp :
            res.append(string[i])
    res = "".join(res)
    return res

while 1 :
    new_string = convert(s)
    if s == new_string :
        print(s)
        break
    if new_string == '' :
        print('EMPTY')
        break
    s = new_string
                

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

思路 : 这道题思路还是很好想的 无非就是让重合次数最多的区间的值尽可能的大 所以我们只需要算出每一个点被几个区间所包含再排序 将原数组里的值由大到小赋给被排好序的点即可

import copy
n = int(input())
numList = list(map(int,input().split()))
temp = copy.deepcopy(numList)
temp.insert(0,0)
numList.sort()
m = int(input())
cmd = []
for i in range(m) :
    cmd.append(list(map(int,input().split())))

numList.insert(0,0)
count = dict((i,0)for i in range(1,n+1)) # 用字段储存每个点的访问次数
for item in cmd :
    for i in range(item[0],item[1]+1) :
        count[i] += 1

newCount = []
for i in count.keys() :
    newCount.append((i,count[i])) # 将字典转化为元组排序
newCount.sort(key=lambda x:x[1],reverse=True)

ans = [0 for i in range(n+1)]
for i in range(n) :
    tmp1,tmp2 = newCount[i]
    tmp = numList.pop() # 取出最大的数
    ans[tmp1] = tmp
out = 0
for i in range(m) :
    out += (sum(ans[cmd[i][0]:cmd[i][1]+1])-sum(temp[cmd[i][0]:cmd[i][1]+1]))
print(out)

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

这题... KS可以很明确地说不可能AC了 考场时我的思路是看能不能找到每组数的规律[1,3]

[1,4],[1,5]... 奈何时间有限 消磨了不少时间最后也没找到规律 不知道是不是思路错了 没有办法只能写了个暴力上去... 能骗几分算几分吧...


import itertools

n = int(input())
numList = [i for i in range(1,n+1)]
def check(lst) :
    res = []
    for i in range(len(lst)) :
        tmp = 0
        for j in range(i) :
            if lst[i] > lst[j] :
                tmp += 1
        res.append(tmp)
    return sum(res)%998244353
ans = 0
for item in itertools.permutations(numList) :
    ans = (ans + check(list(item)))%998244353
print(ans)

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 思路 : 最长上升子序列模版题了 特判一下是否为全上升的序列 若不是 直接输出最长上升子序列+K即可 否则输出N


def check(lst) :
    for i in range(1,len(lst)) :
        if lst[i] < lst[i-1] :
            return False
    return True

N,K = map(int,input().split())
numList = list(map(int,input().split()))
if check(numList) :
    print(N)
else :
    dp = [1 for i in range(N)]
    for i in range(N) :
        for j in range(i) :
            if numList[i] >= numList[j] :
                dp[i] = max(dp[i],dp[j]+1)
    ans = dp[-1] + K
    print(ans)

 

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 思路:贪心+模拟 while循环 只要还有相邻的两个数都不为0 就一起-1 直到不能再减为止 此时剩下数的和是几就加几

import copy
n,K = map(int,input().split())
numList = list(map(int,input().split()))
count = 0
def check(lst) :
    if 0 in lst :
        return False
    return True
while 1 :
    tmp = copy.deepcopy(numList)
    for i in range(n-K+1) :
        if check(numList[i:i+K]) :
            count += 1
            for j in range(i,i+K) :
                numList[j] -= 1
    if tmp == numList :
        break
for i in range(n) :
    count += numList[i] 
print(count)

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS1Pmg7PljrvmtbflupU=,size_20,color_FFFFFF,t_70,g_se,x_16

 思路 : 这题考查方向主要还是数论 具体来说 :有这样几类数是表示不出来的 :

1 质数

2 合数 但该合数不断除2或者不断除3后得到了个质数

3 不断除2直到不能除 再不断除3 若只能除一次3 则不符合

或者不断除3 再不断除2 若只能除一次2 则不符合 

import copy
T = int(input())
cmd = []
for i in range(T) :
    cmd.append(int(input()))
maxNum = max(cmd)
flag = [True for i in range(maxNum+1)]
for i in range(2,int(maxNum**(0.5))+1) :
    if flag[i] :
        tmp = i + i
        while tmp <= maxNum :
            flag[tmp] = False
            tmp += i
flag[0],flag[1] = False,False

def check1(num) :
    tmp1 = copy.deepcopy(num)
    while tmp1%3 == 0 :
        tmp1 //= 3
    count = 0
    while tmp1%2 == 0 :
        tmp1 //= 2
        count += 1
    if count == 1 :
        return False
    tmp2 = copy.deepcopy(num)
    count = 0
    while tmp2%2 == 0 :
        tmp2 //= 2
    while tmp2%3 == 0 :
        tmp2 //= 3
        count += 1
    if count == 1 :
        return False
    return True
def check2(num) :
    if flag[num] == False :
        return True
    return False
def check3(num) :
    tmp1 = copy.deepcopy(num)
    tmp2 = copy.deepcopy(num)
    while tmp1 % 2 == 0 :
        tmp1 //= 2 
    if flag[tmp1] == True and tmp1 != 3:
        return False
    while tmp2 % 3 == 0 :
        tmp2 //= 3 
    if flag[tmp2] == True and tmp2 != 2:
        return False
    return True

for item in cmd :
    if check2(item) :
        if check3(item) :
            if check1(item) :
                print('yes')
            else :
                print('no')
        else :
            print('no')
    else :
        print('no')

————————————————————————————

写在最后 : 一年一次蓝桥杯省赛就这样结束了 我相信认真准备的人一定会有所收获 如果我运气够好 我们国赛再见!🌹🌹🌹

 

  • 10
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
蓝桥杯是一个国内著名的计算机比赛,为了帮助参赛者更好地准备和了解比赛的题型,委会会公布历年的真题并提供相应的题解。 首先,我们需要了解蓝桥杯是一个综合性的计算机比赛,测试的对象包括计算机基础知识、编程能力以及解决实际问题的能力。 在历年的真题中,参赛者将面临不同类型的题目,包括算法设计与优化问题、数据结构与算法问题、编程题等。其中针对Python B的题目主要考察的是对Python语言的掌握和应用能力。 题目解答一般会包含以下几个方面的内容: 1. 题目分析与理解:读取题目,理解题目的要求和限制条件。通过仔细分析题目,确定题目的输入与输出,以及问题的核心。 2. 设计解决方案:根据题目要求和限制条件,设计一个合适的解决方案。可以使用合适的算法和数据结构来解决问题,并做出相应的性能优化。 3. 编写代码实现:根据设计的方案编写相应的代码实现。需要注意的是,Python语言有其独特的语法和特性,掌握好这些特性可以更好地完成编程任务。 4. 调试与测试:编写完代码后,需要进行调试和测试。通过运行样例输入和输出,检查代码是否符合题目要求,并且没有逻辑上的错误。 5. 总结与优化:在完成题目解答后,可以进行总结和优化。包括分析算法复杂度、代码风格和可读性等方面,以便在比赛中更好地表现。 在准备蓝桥杯时,可以通过阅读历年的真题和题解来了解比赛的难度和类型,针对性地进行练习和提高。同时也可以参加相关的培训班和讨论活动,与其他参赛者交流经验和技巧。 总而言之,历年蓝桥杯真题的解答对于提高自己的编程能力和应对比赛非常有帮助。通过认真分析和实践,可以更好地理解并掌握Python编程,并在比赛中取得更好的成绩。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UESTC_KS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值