第十六届蓝桥杯Python B组

以下仅为个人思路(欢迎评论区讨论)


A.攻击次数(模拟)(洛谷:AC了)

ans = 0
blood = 2025
while blood > 0:
    ans += 1
    blood -= 5
    if ans % 2 == 0:
        blood -= 2
    else:
        blood -= 15

    if ans % 3 == 0:
        blood -= 7
    elif ans % 3 == 1:
        blood -= 2
    else:
        blood -= 10
print(ans)

B.最长字符串(考察文件操作)(洛谷:WA了)

l = []

with open('words', 'r+') as f:
    for i in f.readlines():
        l.append(i.strip()) # 讲文件读入传到数组中
# for i in l:
#     print(i)
# lambda表达式排序, 第一个参数排长度倒序(多到少),第二个参数排字典序(小到大)
res = sorted(l, key=lambda x:(-len(x), x))
# 最后输出res数组中第一个参数
print(res[0])

C.LQ图形(模拟)(洛谷:AC了)

# 字符宽, 竖高, 横宽
w, h, v = map(int, input().split())
for i in range(h):
    print('Q'*w)
for i in range(w):
    print('Q'*(w+v))

D.最多次数(贪心)(洛谷:AC了)

s = input()
n = len(s)
st = set(['lqb','lbq','qlb','qbl','blq','bql'])
l = 0
r = 1
ans = 0
while l < n:
    if r > n: break
    if s[r-1] == 'l' or s[r-1] == 'q' or s[r-1] == 'b': # 属于l q b 就判断
        cur = s[l: r] # 当前单词
        if r-l == 3 and cur in st: # 如果数量为3并且满足要求就计数加一
            ans += 1
            l = r # 更新下次访问的字符的新坐标
        elif r-l == 3: # 达到三个字符没有满足要求就把第一个字符弹出也就是左指针加一
            l += 1
            continue
        r += 1 # 成功操作完就右边加1
    else:
        l = r # 遇到非法字符直接跳过
        r += 1
print(ans)

E.A*B problem(赛时不会感觉是找规律结论题)(洛谷:WA了)

回顾的时候感觉就是树状数组
范围是2^20 = 1048576 可以开2e6
2e6 开2次方根 = 1000
可以在每次计算之后,插入到树状数组中,去更新数组,最后O(1)查询
赛时直接跑暴力

for i in range(50):
    for j in range(50):
        for k in range(50):
            for h in range(50):
                pass

**AC代码:**
l = int(input())
d = [0] * (l + 1)
for i in range(1, l + 1):
    j = i
    while j <= l:
        d[j] += 1
        j += i
s = [0] * (l + 1)
for i in range(1, l + 1):
	s[i] = s[i-1] + d[i]
ans = 0
for i in range(1, l):
	tmx = l - i
	ans += d[i] * s[tmx]
print(ans)

F.园艺

思路 第一层for循环间隔数(1~n-1)
第二层for循环每个位置为起点
第三层for循环统计个数
应该只能过60%
但是在洛谷之间AC了,有点懵

n = int(input())
a = list(map(int, input().split()))
ans = 0
# 赛时暴力写法
for i in range(1, n): # 枚举间隔1~n-1
    for idx in range(n): # 枚举每个位置为起点出发
        cnt = 1 # 计当前连续次数
        mx = a[idx]
        idx += i
        while idx < n:
            if a[idx] > mx: # 符合条件加一
                cnt += 1
                mx = a[idx]
            else:
                # 设为起点重新开始
                ans = max(ans, cnt)
                cnt = 1
                mx = a[idx]
            idx += i
        ans = max(cnt, ans)
print(ans)

G.书架还原(个人思路)(洛谷:AC了)

思路:
例如:1 3 4 5 2
把下标i和对应的a[i]存入dict中
dic = { 1:1,
2:3,
3:4,
4:5,
5:2}
我们从下标1去访问,当dic[i] == i时直接跳过
否则的话遍历它的值:

# 1 3 4 5 2
# 当i等于1的时候跳过了
# 当i等于2的时候
cur = i # 让cur等于当前下标(做个记号暂存)
now = dic[i] # 让now为当前下标i对应的值
# 然后我们一直循环下去,直到cur == dic[i]时,
# 这时候就形成了一个闭环,那么排序这一段所花费的次数就为这个循环的次数		

代码实现:(仅为个人思路,可能是错的,大佬们可以指点一下) 大概思路和代码是这样

n = int(input())
a = list(map(int, input().split()))
dic = {}
for i in range(n):
	dic[i+1] = a[i]
cur = 0
ans = 0
idx = 1
while idx <= n:
	if dic[idx] == idx:
		idx += 1
	else:
		cur = idx 
		now = dic[idx]
		while cur != now:
			ans += 1
			ne = dic[now]
			dic[now] = now
			now = ne
			if now == cur:
				dic[now] = now
				break
# print(dic)
print(ans)

H.异或和(不会~写的暴力)(暴力40%)

n = int(input())
a = list(map(int, input().split()))
ans = 0
for i in range(1, n):
	for j in range(i + 1, n):
		ans += (a[i]^a[j]) * (j - i)
print(ans)

祝大家都是省一!

你可能感兴趣的:(蓝桥杯)