AtCoder Beginner Contest 183

AC代码

A - ReLU

输入,输出。

B - Billiards

假设向点\((x, 0)\)处踢符合条件,此时根据反射角相等可以得到\(\frac{S_y}{x - S_x} = \frac{G_y}{G_x - x}\),解得\(x = \frac{S_x \cdot G_y + S_y \cdot G_x}{G_y + S_y}\)

C - Travel

利用std里的next_permutation函数枚举所有排列,然后模拟就完事了。

D - Water Heater

把人看成两个操作,在\(S_i\)时执行\(sum = sum + p_i\),在\(T_i\)时执行\(sum = sum - p_i\)

注意到时间的值域为\([0, 2 \times 10^5]\),所以可以扫一遍时间,把当前时刻发生的操作执行完之后判断一下就完事了。注意要先删再加。

如果存在某个时间\(sum\)大于\(W\),则输出NO,否则输出YES。

E - Queen on Grid

很明显的一道DP题。

\(dp_{i, j}\)为从\((1, 1)\)走到\((i, j)\)的方法数。则\(dp_{i, j}\)可以从三个方向转移过来:左,上,左上。如果枚举每个方向,然后暴力扫一遍这个方向上直至遇到墙的所有点,用这些点来更新当前点,那么就可以得到一个\(O(n^3)\)的DP。

很明显,这个复杂度在这题的数据量下会TLE,所以需要再优化一下。

利用前缀和的思想去优化就可以将这题优化到\(O(n^2)\)

F - Confluence

题面明示了这题并查集。

为每个节点开一个map,map[id]表示以这个点为代表节点的集合中,\(id\)班的学生数量。

在并查集merge操作的时候,可能会合并两个集和,这个时候只需要合并两个代表节点的map,就可以得到合并之后的结果。

但是有一个问题就是暴力合并的话时间复杂度会被卡到\(O(n^2)\)。比如构造数据,从左至右不断合并,这个时候的时间复杂度就是\(\sum_{i = 1}^{n - 1}i = O(n^2)\)

利用启发式合并去优化,既每次merge的时候,总是将较小的那个集和合并到另外一个集和,这样时间复杂度可以优化到\(O(n \log n)\)

posted @ 2020-11-15 21:46  _Backl1ght  阅读(257)  评论(0编辑  收藏  举报