【蓝桥杯真题】16天冲刺 Python

简介: 【蓝桥杯真题】16天冲刺 Python

距离比赛很快了,希望和我一起准备的PY党能更加熟练的掌握Python!

1.距离和(模拟赛填空题)

问题描述:

两个字母之间的距离定义为它们在字母表中位置的距离。例如 A和 C 的距离为 2,L 和 Q 的距离为 5。


对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。


例如:ZOO 的内部距离为 22,其中 ZZ 和 OO 的距离为 11。


请问,LANQIAO 的内部距离是多少?

s=input()
ans=0
for i in range(len(s)):
    for j in range(i+1,len(s)):
        ans+=abs(ord(s[i])-ord(s[j]))
print(ans)

题目分析 :

就是考察一个Ascii码,两个字母Ascci差值的绝对值就是距离

两层循环遍历 累加即可


2.扩散


本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。


小蓝在一张无限大的特殊画布上作画。


这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。


小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)


只有这几个格子上有黑色,其它位置都是白色的。


每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。


请问,经过 2020 分钟后,画布上有多少个格子是黑色的。


题目分析 :


考察一个多源BFS,可以借鉴ACwing模拟赛农田灌溉那题,一样一样的,我在这篇博客写了详细的解析:【蓝桥杯真题】18天Python组冲刺 心得总结_Py小郑的博客-CSDN博客


不过这道题,PY伙伴如果用普通的列表来模拟队列,是跑不出来的,太慢了。


因为列表删除和插入的复杂度是O(n),数据量大这题。


需要借助PY自带的库里面的deque(双向队列),它的时间复杂是O(1),半分钟就能跑出来了。


通过这题最主要的还是学习了使用deque,帮助我们提高速度!

import collections
dx=[-1,1,0,0]
dy=[0,0,1,-1]
pre={(0,0):(0,0),(2020, 11):(2020,11),(11, 14):(11, 14),(2000, 2000):(2000, 2000)}
ans=4
queue=collections.deque()
queue.append((0,0,0))
queue.append((2020, 11, 0))
queue.append((11, 14, 0))
queue.append((2000, 2000, 0))
while queue:
    t=queue.popleft()
    if t[2]==2020:
        print(ans)
        break
    else:
        for i in range(4):
            nx,ny=t[0]+dx[i],t[1]+dy[i]
            if (nx,ny) not in pre.keys():
                pre[(nx,ny)]=(t[0],t[1])
                queue.append((nx,ny,t[2]+1))
                ans+=1
#扩散 20312088

3.错误票据

可以看我这篇文章的第一题

蓝桥杯备战练习 python冲击省一_Py小郑的博客-CSDN博客

4.倍数问题

众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 nn 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。

输入描述

第一行包括 2 个正整数 n, K。

第二行 n 个正整数,代表给定的 n 个数。

输出描述

输出一行一个整数代表所求的和。

题目分析:


这道题需要花功夫好好讲解一下,因为小郑也研究了蛮久,上一次没做出来...


在这里特别感激我的一个好兄弟


cf69f255e5954ce0b9623024357ec289.png


我的思路很多从他那里学到的,所以下面的很多分析会引用他的原话(因为讲的太好了!)


首先,暴力的方法,3层for循环肯定是超时的,说明需要改变方法。


设x+y+z=nk (x,y,z,n,k>0) ,那么必然有


(x%k+y%k+z%k)%k=0(依据运算法则得到)


d5962f69aa954f6c9d270eafcd9ef13a.png


问题就转化为,已知原先的n个数构成一个集合A,然后对每个数取余构成一个新集合B,在集合B中,取3个元素使得他们的和是k的倍数,且余数对应的在集合A中的元素相加之后和最大。


我们不妨设置一个字典 dic[i]=[x,y,z...]:代表数字x,y,z..对k取余后的结果是i


由于我们总是希望取的数字较大,不妨前将集合A降序排列(从大到小),这样对所有的数取余后放到字典里,每个key对应的列表一定是从大到小的。


n,k=map(int,input().split())
a=list(map(int,input().split()))
a.sort(reverse=True)
b=dict()
for i in range(len(a)):
    r=a[i]%k
    if r not in b.keys():
        b[r]=[a[i]]
    else:
        b[r].append(a[i])

设置答案为ans,初始为0,接下来就是寻找余数组合(满足之和是k的倍数),并更新ans


如果枚举了前两个余数i,j,那么第三个余数t是唯一确定的,不需要三层循环(尽可能减少循环优化程序)


原因如下 ,设i,j,t都是集合A元素通过对k取余得到的,必然i,j,t均满足范围(0,k)


那么i+j+t必然满足范围(0,3k),那么i+j+t= k or 2k 才符合题意


而i+j满足范围(0,2k),那么当2k>i+j>k,t=2k-i-j,


当0<i+j<k,t=k-i-j,对于一组i,j,i+j的范围是确定的,所以说第三个余数t是唯一确定的

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j

然后就是更新ans了。


对于3个余数,无非三种情况,三个余数相同,两个余数相同,一个余数相同(互异)


如果三个余数相同,且这个余数对应的列表长度(元素个数)>=3,那么是可行解,否则无解,因为凑不出3个数出来


如果两个余数相同,且这个余数对应的列表长度(元素个数)>=3,且第三个余数(与这两个不同的)对应的列表长度(元素个数)>=1(也就是非空),那么是可行解,否则无解


如果一个余数相同,只要这三个互异余数对应的列表非空,存在可行解。


然后不断把ans和可行解比较,ans不断更新变大。事实上,在两个余数相同这种情况下,可以分成3种,因为可以是12,13,23。

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2 and len(b[t])>=1:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2 and len(b[j])>=1:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2 and len(b[i])>=1:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            if len(b[i])>=1 and len(b[j])>=1and len(b[t])>=1:
                ans=max(ans,b[i][0]+b[j][0]+b[t][0])

fb00d6a3c3eb412d908c951d1db6f6ed.png

报了key error,因为key不存在,所以当余数 not in b的时候,就可以直接下一次循环了

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i not in b or j not in b or t not in b:
            continue
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            ans=max(ans,b[i][0]+b[j][0]+b[t][0])

综上代码

2b95927ab589452c80c0560d6565bce0.png

n,k=map(int,input().split())
a=list(map(int,input().split()))
a.sort(reverse=True)
b=dict()
for i in range(len(a)):
    r=a[i]%k
    if r not in b.keys():
        b[r]=[a[i]]
    else:
        b[r].append(a[i])
ans=0
for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i not in b or j not in b or t not in b:
            continue
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            ans=max(ans,b[i][0]+b[j][0]+b[t][0])
print(ans)

如果对你有帮助,留下三连可以吗!

有问题欢迎评论区提问!!

相关文章
|
2月前
|
Python
蓝桥杯练习题(一):Python组之入门训练题
这篇文章是关于蓝桥杯Python组的入门训练题,包括Fibonacci数列、圆的面积、序列求和和A+B问题的具体代码实现和样例输出。
143 0
|
2月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
127 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
2月前
|
人工智能 Python
蓝桥杯练习题(四):Python组之历届试题三十题
关于蓝桥杯Python组历届试题的三十个练习题的总结,包括题目描述、输入输出格式、样例输入输出以及部分题目的解题思路和代码实现。
50 0
蓝桥杯练习题(四):Python组之历届试题三十题
|
2月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(二):Python组之基础练习三十题
蓝桥杯Python编程练习题的集合,包含了三十个不同难度的编程题目,覆盖了基础语法、数据结构和算法等领域。
52 0
|
7月前
|
索引 Python 容器
【备战蓝桥杯】探索Python内置标准库collections的使用
【备战蓝桥杯】探索Python内置标准库collections的使用
102 1
|
7月前
|
开发者 Python
【备战蓝桥杯】如何使用Python 内置模块datetime去计算我与CSDN相遇的天数
【备战蓝桥杯】如何使用Python 内置模块datetime去计算我与CSDN相遇的天数
75 1
|
7月前
|
算法 测试技术 编译器
蓝桥杯-02-python组考点与14届真题
蓝桥杯-02-python组考点与14届真题
|
C++ Python
【蓝桥杯真题】29天备战 Python讲解
【蓝桥杯真题】29天备战 Python讲解
159 1
【蓝桥杯真题】29天备战 Python讲解
|
Python
【蓝桥杯国赛真题】备战24天 Python
【蓝桥杯国赛真题】备战24天 Python
134 0
【蓝桥杯国赛真题】备战24天 Python
|
Python
【蓝桥杯真题】Python备战28天
【蓝桥杯真题】Python备战28天
182 0
【蓝桥杯真题】Python备战28天