写在前面
赛题相较于上一年py b组难度明显降低,或许成为本次比赛最简朴的一套题,当然其中出现了原题,H题为Codeforces原题,分数为1700,裸题(是好事,至少说人话了),题主因时间冲突并未参加正赛,选择了场外vp。个人感觉如果仅有语法底子的话最少可以拿到15分,即通过A题和C题,这样看来最少都得有个省三省二。
本场难度cf预估分数 <=1700。
题解
A 攻击次数 填空题
103 简朴模仿即可,可在草稿纸上手算。
B 最长字符串(填空题)
答案是afplcu,长度为6
- res = set()
- path = r"words.txt"
- with open(path, "r", encoding="utf-8") as f:
- for line in f:
- cur = line.strip()
- res.add((len(cur), cur))
- res = sorted(res)
- is_beautiful = set()
- ans = -1
- l = 0
- for length, word in res:
- v = [0] * 26
- if length == 1:
- for i in word:
- v[ord(i) - ord('a')] += 1
- is_beautiful.add(tuple(v))
- else:
- for i in range(length):
- v[ord(word[i]) - ord('a')] += 1
- v1 = [0] * 26
- t1 = word[:-1]
- for i in range(length - 1):
- v1[ord(t1[i]) - ord('a')] += 1
- if tuple(v1) in is_beautiful:
- is_beautiful.add(tuple(v))
- if length > l:
- l = length
- ans = word
- elif length == l and word < ans:
- ans = word
- print(l)
- print(ans)
复制代码 C LQ图形
思绪:签到题,按题意模仿即可
- w, h, v = map(int, input().split())
- for _ in range(h):
- print('Q' * w)
- for _ in range(w):
- print('Q' * (v + w))
复制代码 D 最多次数
思绪:贪婪,注意到先选总是不劣于后选即可
- s = input()
- n = len(s)
- count = 0
- i = 0
- while i <= n - 3:
- a, b, c = s[i], s[i+1], s[i+2]
- if {a, b, c} == {'l', 'q', 'b'}:
- count += 1
- i += 3
- else:
- i += 1
- print(count)
复制代码 E题 A · B Problem
思绪:用调和级数nlogn预处理出1 - L 每个数的因数个数再O(L)处理出小于等于x的数的乘积对数
末了罗列XA · XB的值即可
- L = int(input())
- inv = [0] * (L+1)
- for i in range(1, L+1):
- for j in range(i, L+1, i):
- inv[j] += 1
- dp = [0] * (L+1)
- for i in range(1, L+1):
- dp[i] = dp[i-1] + inv[i]
- res = 0
- for i in range(1, L):
- res += inv[i] * dp[L - i]
- print(res)
复制代码 F 园艺

思绪:动态规划 n^2的解, dp[j]表示以第i棵树为起点,间隔为j最多可以保留几颗树
不难观察到有dp[j] = dp[i + j][j] + 1 if tree[i+j] > tree else 1
- n = int(input())
- line = list(map(int, input().split()))
- dp = [[0] * n for _ in range(n)]
- res = 0
- for i in range(n - 1, -1, -1):
- for j in range(1, n):
- if i + j < n:
- if line[i + j] > line[i]:
- dp[i][j] = dp[i + j][j] + 1
- else:
- dp[i][j] = 1
- else:
- dp[i][j] = 1
- res = max(res, dp[i][j])
- print(res)
复制代码 从数据范围来看,显然不是正解,欢迎在批评区分享你的做法。
G 书架还原
你没看错,这题很裸,就差把“置换环”告诉你了。这里提供两种做法。
- n = int(input())
- a = list(map(int, input().split()))
- def G1(a):
- visited = [False] * n
- cycles = 0
- for i in range(n):
- if not visited[i]:
- j = i
- while not visited[j]:
- visited[j] = True
- j = a[j] - 1
- cycles += 1
- return n - cycles
- def G2(a):
- dic = {}
- for i,x in enumerate(a):
- dic[x] = i
- res = 0
- for val in range(1, n+1):
- val_idx = dic[val]
- cur_idx = val - 1
- if cur_idx == val_idx: continue
- cur = a[cur_idx]
- dic[val] = cur_idx
- dic[cur] = val_idx
- a[val_idx], a[cur_idx] = a[cur_idx], a[val_idx]
- res += 1
- return res
- print(G1(a), G2(a))
复制代码 H 异或和
cf原题链接:https://codeforces.com/problemset/problem/1879/D
是不是一模一样呢
思绪:拆位算贡献 + 二阶后缀和
- n = int(input())
- l = list(map(int, input().split()))
- res = 0
- for i in range(21):
- suf1 = [0] * (n + 1)
- suf2 = [0] * (n + 1)
- for j in range(n-1, -1, -1):
- if (l[j] >> i) & 1:
- suf1[j] = suf1[j+1] + 1
- suf2[j] = suf2[j+1] + suf1[j + 1]
- else:
- suf1[j] = suf1[j+1]
- suf2[j] = suf2[j+1] + suf1[j + 1]
- cnt_1 = suf2[j]
- cnt_0 = (n - j) * (n - j - 1) // 2 - cnt_1
- if (l[j] >> i) & 1:
- res += cnt_0 * (1 << i)
- else:
- res += cnt_1 * (1 << i)
- print(res)
复制代码 写在末了
感谢white_two同学提供的部分代码~
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |