A

大部分同学都是用 py 过的,这里提供一个 c++的简单思路

我们先把所有 排序,这一步可以用 int128 直接相乘实现, 对于相等的,我们只保留周长最小的那一个

现在我们从小到大遍历每一个 ,找到第一个大于 的,显然最优借就是他或者他前面一个数

直接和 比较显然是不行的, 考虑到分母最大只有 , 因此我们取 的前 20 位看为

上下同时乘 将分子变为整数,这样就可以和排序时一样比较

现在只用考虑 哪个和 更接近

把三个分数通分, 最大为

用三个 int128 压下位即可 (口胡做法, 还没测试过

当然也可以直接高精度

B

简单模拟

C

手玩一下即可发现规律

D

我们先把连续相等的段变为一个数, 现在新数组 b 满足,

假如我们跨数操作使前面的一个数变 0 , 那么一定会出现这样一种状态:

因为操作的左边界只会越来越左,因此 ^ 的值不会改变, 即二者必定有一个不为 0

因此对于 b 中的每个元素,我们只能单独使他为 0

答案就是 b的长度减去其中 0 的个数

E

线段树求区间子段和板子题

F

发现操作完后, 最大值仅 2e6

因此预处理从 0 开始增加到 2e6 的答案

每个询问相当于前缀和减一下

G

暴力

枚举一下其中一个数的数量, 另外两个数是多少都时可以确定的

H

简单 dp

维护到每一个位置, 生命值为 h 的最小次数即可

每个位置只会向右向下更新答案, 总复杂度

I

简单图论

只有两种策略

​ 1.只走状态为 1 的边, 走到 n

​ 2.先通过状态为 1 的边到 k, 在通过所有边到 n

先在只有 1 的边的图上跑一次最短路, 再把 0 的边加入再跑一次即可

J

简单模拟

K

一个数往前最多能吃的数量就是一个贪心的 LIS, 即往前比他小的数直接吃掉然后变成这个数, 舍弃比他大的数

往后同理

对于往前和往后, 我们可以用一种左右横跳的方式,把前后的都吃掉--- 哪边大就先把哪边吃了

对于贪心的LIS, 可以 的用单调数据结构维护, 也可以用树状数组, 每次把他前面比他大的数都删除,一个数只会被加入一次,删除一次, 因此复杂度为

L

简单模拟

每个字符串都很小, 用一堆map模拟即可

M

定义 为人在 箱子在 的最小移动次数

我们不需要维护 种情况, 只要存储 30 * 30 * 4种

即对于每一个箱子的位置, 人分别在他上下左右四个位置的答案, 把每一个状态看成一个点,类似最短路更新即可

每次更新相当于箱子移动一格,枚举人可能的所有位置, 即30 * 30

总复杂度为