A
幸运地,第一题没有被卡住。
题意
给定正整数 a,b,求最接近 \dfrac a b 的整数。
题解
显然最接近 \dfrac a b 的整数只可能为 \left\lfloor\dfrac a b\right\rfloor 或者是 \left\lceil\dfrac a b\right\rceil。
判断向上取整和向下取整后的结果与 \dfrac a b 的绝对值即可。
Submission #66079489 - AtCoder Beginner Contest 407。
B
题意没看清导致了爆炸。
没有发现题目有 SPJ,以为要保留 9 位小数,结果是精度误差不超过 10^{-9}。。。幸好后来发现了没有吃罚时。
警钟长鸣。
题意
扔出两个骰子,求朝上的那一面的两个数字之和 \ge x 或者差的绝对值 \ge y 的概率。
题解
根据概率公式,我们可以分别计算出方案总数(其实就是 36 )和满足条件的次数。
最后除以下就行了。但是精度要求可能比较高(?),所以我用了 long double
。
Submission #66087661 - AtCoder Beginner Contest 407。
C
个人认为 C > D。
题意
给定一个字符串 s。
你可以对空字符串执行下面两种操作,求最少操作多少次,可以使其与 s 相同。
A
:在末尾添加 \texttt{0}。B
:每一位数字变为下一位数字,\texttt{9} 变为 \texttt{0}。
题解
神秘构造题。
设 n=|s|。
因为字符串有 n 位,所以我们必然需要 $n$ 次 A
操作来达到位数。故 A
操作的次数是一定的。
定义:在第 i 次 A
后,直到序列结束,总共有 x_i 次 B
操作会影响第 i 位。
容易发现如下性质:
- x_1\ge x_2\ge \cdots \ge x_n\ge 0。
- 最终第 i 位的值 s_j=x_j\bmod 10。
B
操作的总次数为 x_1。
故问题等价转化为,寻找一个非增整数序列 \{x_n\},使得 x_i\equiv s_i\pmod{10},同时 x_1 最小。
可以贪心地从后往前构造:
-
令 x_{n+1}=0。
-
遍历 i=\{n\to 1\},然后取最小的满足同余且不小于 x_{i+1} 的数:
\begin{aligned} x_i&=s_i+10\max\left\{0, \left\lceil\dfrac{z_{i+1}-s_i}{10}\right\rceil\right\}\\ &=s_i+10\max\left\{0,\left\lfloor\dfrac{z_{i+1}-s_i+9}{10}\right\rfloor\right\} \end{aligned}
最终 B
操作次数即为 x_1,故最终按键次数为 n+x_1。
Submission #66098614 - AtCoder Beginner Contest 407(赛时,构造时分讨,可能容易理解)。
Submission #66144711 - AtCoder Beginner Contest 407(赛后,严格按照上述思路)。
D
搜索写挂调试时候数组开小,但是交上去的时候没开回来,喜提一发罚时,警钟长鸣。
变量名写错导致搜索挂掉,警钟长鸣。
题意
给定一个 n\times m 的矩阵,可以用 1\times 2 或者 2\times 1 的物体覆盖。最大化最后未覆盖位置的数值的异或和。
题解
nm\le 20,考虑爆搜。虽然每个位置有 3 种选择,3^{20}\approx3\times 10^9,也许无法通过。
但是,实际上每一个位置如果已经被覆盖了就会直接跳过,所以总状态数并没有这么大,搜索应该是可以接受的。
遍历每一个位置,然后分讨以下放哪种物体或者放不放,最后算一下取个最大值即可。
Submission #66107331 - AtCoder Beginner Contest 407(数组开小祭)。
Submission #66107661 - AtCoder Beginner Contest 407。
E
题意
给定一个序列 \{a_{2n}\}。
定义长度为 2n 的合法括号序列 s 的得分为
最大化该得分。
题解
显然是「单位时长任务最优调度」的经典模型:
- 任务:每个位置 $i$(当该位置为 \texttt{)} 时相当于执行任务)。
- 收益:放成 \texttt{)} 会损失 A_i,故 w_i=-A_i。
- 截至:\left\lfloor\dfrac i 2 \right\rfloor ,因为 1\to i 的前缀中最多只能放 \left\lfloor\dfrac i 2 \right\rfloor 个 \texttt{)}。
- 执行 n 个任务。
那么我们将 A_i 从小到大排序,然后对于每个任务 i:
- 找到它的截止时间 d=\left\lfloor\dfrac i 2 \right\rfloor 所对应的最晚可用的时间槽 \le d。
- 如果存在这样的空槽,就调度到该槽上,并表以为已经占用。
- 否则将其当作 \texttt{(} 。
用并查集维护时槽。