牛客周赛146-计数/哈希+子序列DP+博弈

832 字
4 分钟
牛客周赛146-计数/哈希+子序列DP+博弈

牛客周赛146-计数/哈希+子序列DP+博弈#

牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

Easy:A、B

Mid:C、D、E

Hard:F

C-计数+哈希

题意:

给定平面上互不相同的n个点,选出三个构成三角形,满足:非退化的等腰三角行

题解:

枚举水平和垂直类似,下面是按Y坐标分组的讨论:

将相同y坐标的点,对其x坐标按照奇偶分类,对于每一类,计算其第三点坐标的x值,此情况下可构成的答案即为该x坐标对应的点的数量,需要剔除三点共线的情况

计数+哈希
from collections import defaultdict
n = int(input())
xx = defaultdict(set)
yy = defaultdict(set)
for _ in range(n):
x, y = map(int, input().split())
xx[x].add(y)
yy[y].add(x)
ans = 0
for y, xs in yy.items():
even = []
odd = []
for x in xs:
if x % 2 == 0:
even.append(x)
else:
odd.append(x)
for len_ in (even, odd):
for i in range(len(len_)):
x1 = len_[i]
for j in range(i + 1, len(len_)):
x2 = len_[j]
mid_x = (x1 + x2) // 2
if mid_x in xx:
cnt = len(xx[mid_x])
if y in xx[mid_x]:
cnt -= 1
ans += cnt
for x, ys in xx.items():
even = []
odd = []
for y in ys:
if y % 2 == 0:
even.append(y)
else:
odd.append(y)
for len_ in (even, odd):
for i in range(len(len_)):
y1 = len_[i]
for j in range(i + 1, len(len_)):
y2 = len_[j]
mid_y = (y1 + y2) // 2
if mid_y in yy:
cnt = len(yy[mid_y])
if x in yy[mid_y]:
cnt -= 1
ans += cnt
print(ans)
D-子序列DP

题意:

给定一个由数字构成的字符串,计算该字符串中有多少个子序列满足:将该子序列转化为10进制数,该十进制数是6的倍数

题解:

DP定义:

dp[r]表示处理到当前位置时,所有已构造的非空子序列中,数值模6等于r的结果

DP初始化:

dp = [0,0,0,0,0,0]

DP状态转移方程:

对于当前处理的数字d,新的DP值ndp由以下三部分组成:

1.不选当前字符:ndp[r] = dp[r]

2.新建只包含当前字符的子序列:ndp[d%6] += 1

3.将当前字符追加到已有子序列末尾:对于每个r∈(0,1,2,3,4,5,6):ndp[(r*10 + d)%6] = ndp[(r*10 + d)%6] + dp[r]

DP
MOD = 998244353
n = int(input())
s = input().strip()
dp = [0] * 6
ans = 0
for ch in s:
d = int(ch)
ndp = dp[:]
ndp[d % 6] = (ndp[d % 6] + 1) % MOD
for r in range(6):
nr = (r * 10 + d) % 6
ndp[nr] = (ndp[nr] + dp[r]) % MOD
dp = ndp
print(dp[0] % MOD)
E-博弈

题意:

有n堆石头,每堆有若干个石子,用ai表示

x和y进行一场游戏,由x先手,选一个整数b,要求b不小于上一步操作所选的数值,之后选择任意一个至少含有b个石子的堆,从中拿走b个石子

如果轮到某人时,其无法操作,则判输

题解:

先手必胜策略:

先手找到出现奇次的堆,从中取走对应的石子,那么之后每当后手操作,先手在配对的堆中模仿即可

后手必胜策略:

所有堆出现的次数都是偶数,先手在任一堆取x,后手在配对堆也取x,每次操作所有石子频率保持偶数,先手最终面对全0状态

博弈
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
cnt = {}
for x in a:
cnt[x] = cnt.get(x, 0) + 1
if all(v % 2 == 0 for v in cnt.values()):
print("fang")
else:
print("red")
牛客周赛146-计数/哈希+子序列DP+博弈
http://blog.7a7a68.xyz/posts/牛客周赛146-计数-哈希子序列dp--博弈/
作者
Waning
发布于
2026-06-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Waning
愿你明日如绚丽之花.
公告
还活着.
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
56
分类
8
标签
20
总字数
125,693
运行时长
0
最后活动
0 天前

目录