首先不得不吐槽一下,这监考和咨询服务是真**的**
蓝桥杯这次绝对是厕所战神杯了,肯定还有一堆车队
既然这样,而且也不能退钱,我就随意打了,心态非常的好,好像系统有个bug会不停黄牌警告,我根本没管,题目我分析出样例有问题,直接自己就改了,懒得咨询。双机位监考的手机不停的有人找志愿者说这说那,也没管。好像外界的一切都影响不了我了,整场比赛居然还意外的享受。
下面来分享下我的解法,带思考过程带赛时代码
不保对,有问题可以讨论
A题
4+19+20*21=443
B题
似乎是中国剩余定理,但我不会写这个算法,赛时打表找的规律
我先随便选了个12,13,找满足他们余数的数,发现这些数都隔了一个恒定的数
既然这样,我固定第一个数,然后让他们每次跳这个恒定的数不就行了
先暴力找满足2-9的余数的数,以及恒定间隔数。
以这个数开始再暴力跳10-22,最后我看这个数够大了,直接让他跳最后答案了,跳23-49
共三次,跳出答案为:
2022040920220409
恰好是2022年04月09号重复两遍
如果他们不设这个答案我可能还会再检查一下的,毕竟这方法太诡异了
C题
质因数分解模板+一点点变动
n = int(input())
i = 2
ans = 0
while i * i <= n:
if n % i == 0:
ans += 1
while n % i == 0:
n //= i
i += 1
if n != 1:
ans += 1
print(ans)D题
实质就是让边尽量贴在一起
比赛时多画一画,找找规律,防止漏情况
接下来就是分类讨论:
最理想的就是三个矩形有三条边都相同
那直接叠就行了,这种情况多边形四条边
次之的情况就是有两个矩形的两条边可以合成另一矩形的一条边,且合成的两个矩形除用来合成的边之外的两条边等长,也合成了一个大矩形,四条边。 若用来拼的两个矩形的另外两条边不相等,就会变成6条边
再次之的情况就是只有两个矩形有两条边相同
那么就是这样,六条边

最烂的情况就如下,八条边

代码比赛时因为懒得想,打了最直接的一种,有点丑,懂个意思就好
T = int(input())
for _ in range(T):
ans = 8
a = list(map(int, input().split()))
a = [[a[i], a[i + 1]] for i in range(0, 6, 2)]
for i in range(3):
for x1 in range(2):
for j in range(3):
if i == j:
continue
for x2 in range(2):
if a[i][x1] == a[j][x2]:
ans = min(ans, 6)
for k in range(3):
if j == k or i == k:
continue
for x3 in range(2):
if a[i][x1] == a[j][x2] and a[j][x2] == a[k][x3]:
ans = min(ans, 4)
if a[i][x1] == a[j][x2] + a[k][x3]:
if a[j][x2 ^ 1] == a[k][x3 ^ 1]:
ans = min(ans, 4)
else:
ans = min(ans, 6)
print(ans)E题
你敢信嘛,这题我忘了自己打的是个暴力了,于是忘记回去打正解了,一直想最后一题了
不过赛后想了一下,也没想到比较好打的正解,有好想法可以分享下
暴力就直接模拟,按题目意思来
s = input()
tag = 1
while tag and len(s):
n = len(s)
a = [0] * n
ns = ''
for i in range(1, n - 1):
if s[i] == s[i - 1] and s[i] != s[i + 1]:
a[i], a[i + 1] = 1, 1
if s[i] != s[i - 1] and s[i] == s[i + 1]:
a[i], a[i - 1] = 1, 1
for i in range(n):
if a[i] == 0:
ns += s[i]
if s != ns:
s = ns
tag = 1
else:
tag = 0
if len(s) == 0:
print('EMPTY')
else:
print(s)F题,差分+贪心
既然可以随便排列,肯定让加和最多次的和最大的数相乘,如此可以得最大值
题面数据范围我也不晓得是不是有问题,怕出错,所以在l,r那边加了个判断
n = int(input())
a = [0] + list(map(int, input().split()))
m = int(input())
s = [0] * (n + 10)
ans, nans = 0, 0
for _ in range(m):
l, r = map(int, input().split())
if l > n:
continue
r = min(r, n)
s[l] += 1
s[r + 1] -= 1
for i in range(1, n + 1):
s[i] += s[i - 1]
ans += s[i] * a[i]
s.sort(reverse=True)
a.sort(reverse=True)
for i in range(n):
nans += a[i] * s[i]
print(nans - ans)G题,打表找的规律
打表切入点:对排列中每个数的具体贡献值进行数据分析
下面是用于打表的辅助程序,你们自己运行下也能看出规律
from itertools import permutations
n = int(input())
a = [i for i in range(1, n + 1)]
tot = [0] * (n + 1)
for s in permutations(a):
for i in range(n):
for j in range(i):
tot[s[i]] += s[j] < s[i]
print(tot)赛时程序
n = int(input())
ans = 1
for i in range(3, n + 1):
ans *= i
ans %= 998244353
ans *= (n * (n - 1) // 2) % 998244353
ans %= 998244353
print(ans)H题,经典最长不下降子序列DP的变种
思路是先找到一个最长不下降子序列并记录位置,然后对最长不下降子序列的每个位置进行DP
一定注意边界问题
对于最长不下降子序列的单个位置,将其后面k位置全换成该位置的值是最优策略,以此为基础进行DP
from bisect import bisect
n, k = map(int, input().split())
a = [0] + list(map(int, input().split()))
dp = [0]
pos = [0]
for i in range(1, n + 1):
if a[i] >= dp[-1]:
dp.append(a[i])
pos.append(i)
continue
p = bisect(dp, a[i])
dp[p] = a[i]
pos[p] = i
ans = 0
for i in range(1, len(dp)):
l = min(pos[i] + k, n)#往后修改k个到达的位置
r = bisect(pos, l)#l位置在最长不下降子序列的相对位置
if r == len(pos):#当前位置已超出子序列范围
#i为这个节点及其前面多少节点,l-pos[i]为新增的
ans = max(ans, i + l - pos[i])
else:#未超过
#未超过则还要加上子序列后面剩下的长度
ans = max(ans, i + l - pos[i] + len(pos) - r)
print(ans)I题,差分+贪心
我是想着从左边开始,找一个最长的连续单调序列,单调递增或者单调递减都行,然后对该序列进行处理,再继续往右移动找单调序列
代码打的挺丑的,估计是错的,建议别看
n, k = map(int, input().split())
a = list(map(int, input().split()))
st = []
ans = 0
for i in range(n):
if i == n - 1:
st.append(a[i])
s = [0] * (len(st) + 1)
if st[0] >= st[-1]:
st = st[::-1]
for j in range(len(st)):
if j > 0:
s[j] += s[j - 1]
st[j] -= s[j]
ans += st[j]
s[min(j + 1, len(st))] += st[j]
s[min(j + k, len(st))] -= st[j]
break
if len(st) < 2 or a[i] == st[-1]:
st.append(a[i])
else:
if (a[i] < st[-1]) == (st[-1] < st[0]):
st.append(a[i])
else:
s = [0] * (len(st) + 1)
if st[0] >= st[-1]:
st = st[::-1]
for j in range(len(st)):
if j > 0:
s[j] += s[j - 1]
st[j] -= s[j]
ans += st[j]
s[min(j + 1, len(st))] += st[j]
s[min(j + k, len(st))] -= st[j]
print(ans)J题,没想到什么好算法
直接暴力
import math
T = int(input())
for _ in range(T):
a = int(input())
i = 2
p = a
tag = 0
while i * i <= a:
if a % i == 0:
tot = 1
while a % i == 0:
a //= i
tot *= i
if tot != i:
s = p // tot
if int(math.sqrt(s)) ** 2 == s:
tag = 1
break
i += 1
if tag:
print('yes')
else:
print('no')