蓝桥杯冲刺Day1 Python B组题解
·
攻击次数
题解:
sums = 0
def check(sums):
if sums>=2025:
return True
else:
return False
attack1 = 5
i = 0
while not check(sums):
i+=1
sums+=attack1
if i % 2 == 0:
attack2 = 2
else:
attack2 = 15
sums += attack2
if i % 3 == 1:
attack3 = 2
elif i % 3 == 2:
attack3 = 10
else:
attack3 = 7
sums+= attack3
if check(sums):
print(i)
注意一下while not check(sums)这个写法
LQ图形
题解:
import os
import sys
s = list(map(int,input().split()))
w = s[0]
h = s[1]
v = s[2]
for i in range(1,h+1):
for j in range(1,w+1):
print("Q",end="")
print()
for i in range(1, w+ 1):
for j in range(1,v+w+1):
print("Q",end = "")
print()
注意问题:
- 默认的print语法打印完就自动换行,想要在同一行中输出应该用end = ""
- 注意缩进
考察输入输出
| 输入场景 | 代码模板 | 解释 |
|---|---|---|
| 读一个数字 | n = int(input()) |
读入整数 |
| 读一个字符串 | s = input().strip() |
读入字符串,去空格 |
| 读一行多个数字 | nums = list(map(int, input().split())) |
最常用! 存成数字列表 |
| 读一行多个字符串 | strs = input().split() |
存成字符串列表 |
| 读 N 行数据 | for _ in range(n):<br> s = input().strip() |
循环读入 n 行 |
Q1:什么时候用map
map的核心作用是把一串字符统一转换成指定类型
- 一行输入多个数字
- 多变量赋值
- 输入的是字符串用map(str,....),但是一般直接用input().split()就行
- 不能直接map(str,input()),必须配合split(),因为input()读进来是一个整体字符串,split()才会切开
Q2:什么时候用list
- map用完必须转list
- 想要修改字符串的某一位,字符串在python里是不可变的,必须转成字符列表list
# 场景:读取一行数字并保存为列表 nums = list(map(int, input().split())) # 解释: # 1. input() 读入 "1 2 3" # 2. split() 切成 ["1", "2", "3"] # 3. map(int, ...) 转成 (1, 2, 3) # 4. list(...) 转成 [1, 2, 3] 这个列表,存进 nums # 场景:修改字符串的某一位(必须转list) s = "abc" lst = list(s) # 转成 ['a', 'b', 'c'] lst[1] = 'x' # 修改第二位 s = ''.join(lst) # 再转回字符串
Q3:什么叫.strip()
- 默认情况下,它去掉首尾的空格、换行符(\n)、制表符(\t)。
# 最常用的两种 #读取一行多个数字 nums = list(map(int, input().split())) # 读取下一行字符串 s = input().strip()
最长字符串
题解:
import os
import sys
words = sys.stdin.read().split()
bc = ""
bt = set()
words.sort(key = lambda x:len(x))
for i in words:
if len(i) == 1 or ''.join(sorted(i[:-1])) in bt:
bt.add(''.join(sorted(i)))
if len(i)>len(bc):
bc = i
if len(i) == len(bc) and i<bc:
#这一步是在判断字典序谁更小
bc = i
print(bc)
需要注意的点有:
- 系统读取输入输出
- 集合转换,以及判断元素在不在集合中的in操作
- 排序sort中的lambda特殊用法,还有sorted
- 切片
- join,‘’的用法
有几步很难看懂,逐步拆解一下:
''.join(sorted(i[:-1])) in bt
= 【去掉最后一个字符的子串】是优美字符串
#第一步:切片,i[:-1]
#第二步:sorted(...)把字符按字母顺序排序,返回一个字符列表
sorted("cb")→["b","c"]
#第三步:把列表拼回字符串,用join
''.join(["b"]) → "b"
# ''就是空字符串,意思是拼接列表里的字符时中间不加任何东西
# join()就是把列表里的字符拼起来变回字符串
#第四步:判断是不是在集合bt里
先记住一个铁律
sorted(字符串) → 输出的是 字符列表,不是字符串!列表不能直接放进集合里判断 in,必须转回字符串,这就是 ''.join() 的唯一作用!
'任意符号'.join(列表) = 拼接,但是无缝拼接做题最常用)。
考查系统输入输出
| 代码 | 作用 | 适用场景 |
|---|---|---|
input() |
读一行 | 读单个数字、单行数据 |
sys.stdin.read().split() |
读全部输入,切成单词列表 | 题目给一堆单词、批量数据 |
考察set集合查找,字符串处理,切片
- 取子串(本题就是典型)
i[:-1]:去掉最后一个字符(考烂了!)s[1:]:去掉第一个字符s[2:5]:取第 3 到第 5 个字符(左闭右开)
- 字符串反转(省赛填空题常客)
s[::-1]:把字符串倒过来,比如"abc"→"cba"
- 截取固定长度
- 比如题目要求取前 n 个字符:
s[:n] - 取后 n 个字符:
s[-n:]
- 比如题目要求取前 n 个字符:
- 步长切片(偶尔考,但会了加分)
s[::2]:隔一个取一个,比如"abcdef"→"ace"
| 切片写法 | 作用 | 例子(s = "abcde") | 结果 |
|---|---|---|---|
s[:-1] |
去掉最后一个字符 | s[:-1] |
"abcd" |
s[1:] |
去掉第一个字符 | s[1:] |
"bcde" |
s[::-1] |
字符串反转 | s[::-1] |
"edcba" |
s[:3] |
取前 3 个字符 | s[:3] |
"abc" |
s[-2:] |
取后 2 个字符 | s[-2:] |
"de" |
最基础的set集合操作合集
# ===================== 集合(set) 基础操作合集 =====================
# 1. 创建集合 & 列表转集合(自动去重)
print("=== 1. 创建集合 & 去重 ===")
word_list = ["b", "bc", "b", "cbd", "dbca", "bc"] # 带重复的列表
word_set = set(word_list) # 列表转集合,自动去重
print("原列表:", word_list)
print("转集合后:", word_set)
# 2. 判断元素是否在集合中(最常用!蓝桥杯核心)
print("\n=== 2. 判断元素是否存在 ===")
print("'bc' 在集合里吗?", "bc" in word_set)
print("'abc' 在集合里吗?", "abc" in word_set)
print("'ab' 不在集合里吗?", "ab" not in word_set)
# 3. 往集合里添加元素
print("\n=== 3. 添加元素 ===")
word_set.add("abcd") # 添加新元素
word_set.add("b") # 添加重复元素,自动忽略
print("添加后集合:", word_set)
# 4. 删除元素(discard更安全)
print("\n=== 4. 删除元素 ===")
word_set.discard("cbd") # 删除存在的元素
word_set.discard("xxx") # 删除不存在的,不报错
print("删除后集合:", word_set)
# 5. 遍历集合(挨个取出元素)
print("\n=== 5. 遍历集合 ===")
for word in word_set:
print("元素:", word)
# 6. 集合转回列表
print("\n=== 6. 集合转回列表 ===")
word_list_new = list(word_set)
print("转回列表:", word_list_new)
word_list_new.sort() # 列表可以排序
print("排序后列表:", word_list_new)
# 7. 集合交并补(蓝桥杯偶尔考)
print("\n=== 7. 集合交并补 ===")
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print("集合a:", a)
print("集合b:", b)
print("交集(都有的):", a & b)
print("并集(合起来):", a | b)
print("差集(a有b没有的):", a - b)
蓝桥杯只要涉及到频繁查找,必须用集合,数据量大的时候列表会超时报错
列表判断在不在列表里是挨个遍历,集合判断在不在列表里是直接定位
最多次数
import os
import sys
s = input().strip()
target = sorted("lqb")
count = 0
i = 0
while i <= len(s)-3:
if target == sorted(s[i:i+3]):
count+=1
i+=3
else:
i+=1
print(count)
穿越时空之门
题解
def change_bin(num):
num = bin(num)[2:]
sums = 0
for i in num:
sums += int(i)
return sums
def change_four(num):
res = []
# if num == 0:
# return 0
while num >0 :
i = num % 4
res.append(str(i))
num //= 4
s = ''.join(reversed(res))
sums = 0
for j in s:
sums += int(j)
return sums
count = 0
for i in range(1,2025):
if change_bin(i) == change_four(i):
count+=1
print(count)
- 注意一下进制的转换
- 注意一下/和//的区别
考察进制转换
必背模板
def dec_to_k(n, k):
# n: 十进制数
# k: 目标进制
if n == 0: # 特殊情况:0 转任何进制都是 0
return "0"
res = []
while n > 0:
rem = n % k # 取余数
res.append(str(rem))
n = n // k # 取商
# 余数倒序
return ''.join(reversed(res))
# 测试
print(dec_to_k(10, 4)) # 10转4进制 → 22
print(dec_to_k(15, 2)) # 15转2进制 → 1111
print(dec_to_k(26, 5)) # 26转5进制 → 101
连连看
暴力骗分吧
import os
import sys
n,m = list(map(int,input().split()))
D = {}
i= 1
A = []
while i<=n:
row = list(map(int,input().split()))
A.append(row)
i+=1
#键为网格中的数值,值为数值对应的坐标
for i in range(n):
for j in range(m):
val =A[i][j]
coord = (i+1,j+1)
if val not in D:
D[val] = []
D[val].append(coord)
count = 0
#遍历字典里每一个数字的所有坐标
for coords in D.values():
len_coord = len(coords)
for i in range(len(coords)):
a,b = coords[i]
for j in range(len(coords)):
if i == j:
continue
c,d = coords[j]
if abs(a-c) == abs(b-d):
count+=1
print(count)
##这个for coords in D.values(),D.values()是一个二维列表,coords是里面的一维坐标,代表第几个值列表,len(coords)就是这个值列表里有几个坐标
考察二维列表,考察字典
字典蓝桥杯必考用法:
# 1.统计元素出现次数
# 模板
cnt = {}
for x in 列表/字符串:
cnt[x] = cnt.get(x, 0) + 1
# 例子:统计字符串字符
s = "lqblqb"
d = {}
for c in s:
d[c] = d.get(c, 0) + 1
# d = {'l':2, 'q':2, 'b':2}
# 2.键值映射
# 模板
d = {}
for 下标i, 下标j:
key = 数值
val = (i,j)
if key not in d:
d[key] = []
d[key].append(val)
# 3.安全取值
# 没有这个键,返回0,不报错
num = d.get('a', 0)
# 4.遍历字典
##遍历键
for k in d:
print(k)
##遍历值
for v in d.values():
print(v)
##遍历键+值(常用)
for k,v in d.items():
print(k,v)
# 5.去重
d = {}
for idx,num in enumerate([1,2,1,3]):
if num not in d:
d[num] = idx ##只存第一次出现的位置
# 6.找出现最多/最少的元素
# 找出现次数最多的
max_key = max(d, key=d.get)
# 找最少
min_key = min(d, key=d.get)
注意这里的key = d.get不是调用函数,而是把函数当成参数传给max,不能加括号
死记硬背(考场直接用)
- 自己用 → 加括号:
d.get('a')- 传给函数用 → 不加括号:
key=d.get

要拿二维数组的行列下标:双重循环
| 写法 | 是什么 | 用途 |
|---|---|---|
lst[i] |
列表 | 按位置取 |
d[key] |
字典 | 按键取值 / 赋值 |
d.get(x,0) |
字典统计 | 计数专用 |
d[key].append() |
字典里套列表 | 一个键存多个东西 |
注意max遍历字典时,只遍历字典的键,不遍历字典的值
max(d,key = d.get),key是一个函数,会自动调用get拿到这个键所对应的值也就是次数,
max(列表)→ 找列表里最大的数max(字典)→ 找字典里最大的键max(字典, key=字典.get)→ 找值最大对应的键
A-B problems
这个只能通过96%
import os
import sys
l = int(input())
#m1 = xa*xb,m2 = ya*yb
#本质上是一种排列组合,用p的方案数 × q的方案(在剩余可行方案中选)
f= [0]*(l+2)
#求m1 = k的方案总数
for i in range(1,l+1):
for j in range(1,l//i+1):
m = i*j
f[m]+=1
#求m2 <=k的方案总数,因为p+q<=L,所以 q<=L-p,也就是求q的总数
pre = [0]*(l+2)
for i in range(1,l+1):
pre[i] = pre[i-1]+f[i]
ans = 0
for p in range(1,l):
ans+=f[p]*pre[l-p]
print(ans)
考察前缀和
注意的点有
- 数组索引不能越界
- 对暴力四重循环的优化:p+q<=L,拆成两个变量
✅ 空列表 [] 可以用,但分两种情况:
- 追加元素(
append) → 不用初始化长度,直接用[]✔️ - 索引访问 / 赋值(
f[0]、f[5]) → 必须初始化长度,直接用[]一定会报错越界 ❌
用[0]*长度默认每个位置都是0,后面长度设成l+2,有效避免越界
更多推荐


所有评论(0)