The 2020 ICPC Asia Shenyang Regional Programming Contest - Codeforces Gym
B - Whispers of the Old Gods
给出一个正则表达式 pattern
和字符串 str
,要求对字符串中的数字进行尽可能少的插入,删除,替换操作。输出最小的操作次数。
做老题结果发现专业对口这件事
首先根据题目给出的 BNF 写出正则的解析器,然后用 Thompson’s Construction 构造和 pattern
对应的 NFA,
重合 NFA 的起点和 str
的开始符,向后匹配到 NFA 的结束状态即可。当 str
的下一个字符使得 NFA 没有对应转移时,
修改 str
的下一个字符,其实也就相当于一个 01-最短路。
有关 Thompson’s Construction 构造可以参考 Comp412 课件。
- You will be tempted to take shortcuts, such as leaving out some of the ϵ transitions
- Do not do it. Memorize these four patterns. They will keep you out of trouble.
如果预先将题目中的 BNF 处理成 LL(1) 类型的文法,可以进一步优化速度,但是训练的时候推了一下,没写。
附当时的推导结果:
\<regex::\<regex-op::\<regexs::\<atomic-regex ::=\<atomic-regex∣\<regex-op∣\<regexs= "|" \<regex∣ "+" \<regex=\<atomic-regex \<regex∣ϵ=\<digit∣ "[" \<digit-sequence "]"∣ "(" \<regex ")"
D - Journey to Un’Goro
路线中仅包含红蓝两种颜色。输入一个整数,构造一个这样的路线,使的从 i 出发到达j经过的红色数量为奇数的路径的数量最大。
1≤i≤j≤n
输出满足要求的(i,j)的最大数量和这些路线。当路线数量大于100个时,仅输出字典序小的前100个。
赛时没做出来
在此介绍一篇神答案 打表+找规律
将 r
设为 1,b
设为 0。那么子串中 r 的数量就是前缀和之差。
考虑什么时候 r 的数量为奇数:显而易见,当前缀和数组中两个元素的奇偶性不同时,其表示的区间才是奇数。记奇数的个数为 O,偶数的个数为 E。那么在这段区间中,
可以选择任何一个前缀和为奇数的元素和一个前缀和为偶数的元素来构成一个其区间为奇数的子区间。显而易见,这种符合条件的子区间的个数应该是 O×E 个。
根据高中学的某个忘掉名字的不等式,当 O=E时,O×E取最大值,也就是 O 和 E 各取一半的时候。
此时 O=⌈2n+1⌉,E=⌊2n+1⌋(加一是为了考虑前缀和要留出 i = 0 的空间)
根据上述内容,我们一顿爆搜就可以了,当max(O,E)>⌈2n+1⌉ 时直接剪掉即可。
在实际搜索中,我们没必要记录前缀和,只需要维护当前的奇偶状态即可。
F - Kobolds and Catacombs
给你一段序列,将其划分为尽可能多的段,要求每段再重新排序再拼接起来后为非下降序列。
求原序列和排序之后的序列的前缀和,当前缀和元素相等的时候就代表这个位置被分割排序后可以形成非下降序列,此时 ans++
时间复杂度 O(nlogn),瓶颈在排序
能卡着时间过
G - The Witchwood
现在有 n 个甜点,每个甜点能带来 ai的愉悦度,Bob 能吃 k 个甜点。输出 Bob的最大愉悦度是多少。
想必这个就是大名鼎鼎的签到题了
H - The Boomsday Project
某共享单车公司推出了“骑行劵”折扣活动。原本一次骑行需要花费 r 元,一张折扣卷可以在其有效期限的 d 天内免费骑行 k 次。在 t 天购买的折扣劵将在 t+d−1天过期。
折扣劵之间可存在覆盖关系,购买新的骑行劵时,旧的骑行劵作废。
现在有 n 种不同的骑行劵。每种骑行劵需要花费 ci 元购买,在di天内享有ki次免费骑行。一个人可以无限次购买同一种骑行劵。
给出 Aloha 的骑行记录,输出最小花费。
训练时又没做出来
我愿称其为玄学dp。
I - Rise of Shadows
一个钟表,时钟转一圈有 H 小时,分针转一圈有 M 分钟。设 α=HM2πA。问一天中时钟和分针的夹角小于等于 α的时刻有几次。
首先选取时针为参照物,每分钟时针运动角度 ωh绝对=HM2π,分针运动角度 ωm绝对=M2π
其分针相对速度为 ωm=ωm绝对−ωh绝对=HM2π(H−1)
在 T 分钟的时候,时针和分针的夹角为 θ=ωmT=HM2π(H−1)T
考虑到可能会有转一圈回来的情况,夹角应该是 θ=HM2π(H−1)Tmod2π
另外时针和分针的能形成的角有两个,这两个角互补。我们应该选择小的角,即 min(θ,2π−θ)
也就是求从 T∈[0,HM] 这段时间中有多少个 HM2π(H−1)Tmod2π≤HM2πA 或2π−HM2π(H−1)Tmod2π≤HM2πA 成立
在这里,我们很容易发现一种特殊情况,即 A=2HM时,显然每个时刻都满足题意,答案为 HM
当 A=2HM 时:
对于上式HM2π(H−1)Tmod2π≤HM2πA 中,我们可以将 HM 看作 2π,将 (H-1) 每个时刻两个指针的变化量。
当存在 T(H−1)modHM≤A 时,一定不会有 T(H−1)modHM≥HM−A,两个部分不会同时存在重叠的答案,所以我们只需要将两部分的答案
加起来即可。
先看第一个式子(其中 [P] 表示艾弗森括号)
T=0∑HM[T(H−1)modHM≤A]
令 G=gcd(H−1,HM),当G=1时,由于 T∈[0,HM],构成了一个模为 HM 的完全剩余系。
根据其性质可知,T(H−1)modHM也是一个完全剩余系,即它一定取遍了 [0, HM-1] 的每一个数,此时不需要关心那个时刻满足答案,只需要知道范围内有多少
数小于等于 A 即可。现在在 [0,A] 的范围内总共有 A+1 个数满足,答案为 A+1
当 G=1时,利用同余性质 ac≡bc(modb)⇔a≡b(mod(c,d)b),式子看转化为
∑T=0HM[GT(H−1)modGHM≤⌊GA⌋]
也就是相当于把 [0,HM) 平均分成 G 段,每一段的 T 都模一个 GHM 的完全剩余系,,
每一段的答案都是⌊GA⌋+1。即第一个式子的所有答案之和为 G∗(⌊GA⌋+1)
同理,我们处理第二个式子,得到答案为 G∗(2⌊GA⌋+1)
吐槽一下我队友在计算过程中把向下取整掉了
不过这位现场百度5分钟内就把完全剩余系学会了,他就是我的神,tql
K - Scholomance Academ
阅读理解题,读懂题意就是小模拟
结果我比有深度学习经验的队友先读懂
以下翻译的术语可能并不正确
二元分类是一种对已有实例进行分类的算法,分类结果只能是 positive(+)
或 negative(-)
。
典型的二元分类算法用一个函数 S 和一个阈值 θ 进行,当实例的分数 S(x) ≥θ 时,实例x被分类为 positive
,否则就是 negative
显然不同的阈值 θ 会产生不同的分类结果。
二元分类也存在误判。它可以将实际为 positive
的实例判定为 negative
,这种情况称为 false negative
;也可以将实际为 negative
的实例判断为 positive
,这种情况称为 false negative
现在题目给出一个数据集和一个分类器。定义 true positive rate(TPR) 和 false positive rate(FPR) 为以下内容
TPR=\frac{\\#TP}{\\#TP + \\#FN}, FPR=\frac{\\#FP}{\\#TN + \\#FP}
你现在需要评估一个分类器的性能,这个分类器在不同的阈值 θ 下表现的 TPR 与 FPR 不同。记阈值为 θ 时 TPR 和 FPR 为 TPR(θ) 和 FPR(θ)。那么 area under curve(AUC) 为
AUC=∫01maxθ∈RTPR(θ)∣FPR(θ)≤rdr
式子中被积函数称为 receiver operating characteristic(ROC),意为当 FPR(θ)≤r 时 TPR的最大值。
例如现在有三个测试数据,当阈值取值为θ=30时,有3个 TP, 2个 FP,2个TN,1个 FN。
因此,此时的 TPR(30)=0.75,FPR(30)=0.5。当 θ变化时,我们能画出 ROC 曲线,并直接计算出 AUC。如图片1。
输入数据
第一行一个整数 n (2≤n≤106),表示测试集中实例的数量。接下来 n 行中,
每一行包含一个字符 c∈+,− 表示实例的真实类型;一个整数 s (1≤s≤109) 表示当前实例的分数
输出数据
输出 AUC,精确到小数点后10位。
我第一反应是扫描线
首先我们需要明确他那个看着吓人的积分函数根本没有任何用处。
我们可以通过枚举 θ,每次枚举算出 FPR 和 TPR ,并求出面积。这种方法道理上可行,但实际因为取值范围的问题,并不能用。
退而求其次,因为题目还给了当前实例的分数 s,这个s即可表示每次theta的取值。起始时记 θ 为最大值,此时所有的实例都会被预测为 negative
。逐步降低 θ,即可得到最后答案,通过预先根据 s 进行排序,可实现逐步降低。
将 + 排在 − 之前可以便于计算。