ABC407 题解(A~E)

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 操作的次数是一定的。

定义:在第 iA 后,直到序列结束,总共有 x_iB 操作会影响第 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 最小。

可以贪心地从后往前构造:

  1. x_{n+1}=0

  2. 遍历 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 的得分为

\sum\limits a_i\times[s_i=\texttt{(}]

最大化该得分。

题解

显然是「单位时长任务最优调度」的经典模型:

  • 任务:每个位置 $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

  1. 找到它的截止时间 d=\left\lfloor\dfrac i 2 \right\rfloor 所对应的最晚可用的时间槽 \le d
  2. 如果存在这样的空槽,就调度到该槽上,并表以为已经占用。
  3. 否则将其当作 \texttt{(}

用并查集维护时槽。

Submission #66131426 - AtCoder Beginner Contest 407

1 个赞