- 代码源挑战赛 Round 4
代码源挑战赛 Round 4 题解
- 2025-3-28 17:46:24 @
T1
100%
分离出 的百位 、十位 、个位 ,可以参考以下代码:
a = X / 100;
b = (X - a * 100) / 10;
c = X % 10;
答案为 。
注意:由于前导 不输出,所以不能直接输出 ,,。
时间复杂度 。
T2
100%
输入字符串后逐位判断,如果遇到 D
、M
、Y
这三种字符就输出。
注意在过程中记录是否出现过这三种字符,如果没出现,最后要输出 作为答案。
时间复杂度 。
T3
20%
枚举 的质因数 ,找到后不断将 除以 ,计算出指数 ,然后输出 和 。
记 的最大值为 。
时间复杂度 。
40%
将 与 相乘计算出 , 最多只会有一个超过 的质因数存在,因此我们枚举质因数时只需要枚举到 即可。
注意不要漏掉大于 的那个质因数。
时间复杂度 。
100%
对两个或更多个整数的乘积,进行因式分解的结果,等价于对每个整数因式分解后,将相同质因数的指数相加。
所以我们找到 的质因数 并计算出对应指数 后,令 。
都处理完后,按顺序将 的项输出即可。
时间复杂度 。
T4
20%
先枚举哪位同学今天不问问题,再 枚举剩下同学的排队顺序,过程中计算等待的总时间。
时间复杂度 。
40%
对于今天问了问题的同学,他们按 从小到大的顺序排队能让等待时间的总和最小。
将同学按 从小到大的规则排序。因为输出答案时要按同学的编号输出,所以我们可以将每个同学的所需时间 和编号 放在结构体 里一起排序。
两重循环,第一重循环枚举今天不问问题的是同学 ,第二重循环计算剩下 名同学的等待总时间,计算时跳过第 名同学。
计算出的答案可以储存在 里,这样便于按编号输出。
时间复杂度 。
60%
先考虑如果 个同学今天都问了问题,这种情况下 个同学的等待时间的总和为 。
在这个基础上,考虑仅将第 名同学从队伍中去掉,那么等待总时间减去 的等待时间,并且排他后面的每一位同学的等待时间减去 。
用 表示 的同学数量。维护 的同学数量 ,以及 的同学的 之和 。
预处理 和 。
可以将 的位置视为所需时间相同的同学中的最后一个,那么 原本的等待时间 , 后面的人数 。
记 的最大值为 。
时间复杂度 。
100%
排序后维护属性 的前缀和 。
如果同学 排序后位于第 名,那么他原本的等待时间 ,他后面的人数 。
时间复杂度 。
T5
20%
三重循环,外层两重循环枚举区间的左右端点 和 ,内层循环计算区间 的异或和 。
时间复杂度 。
60%
因为 ,所以前缀异或和具有可差分的性质,即 。
因此我们只需要预处理 的前缀异或和 ,然后用两重循环枚举区间的左右端点,用 来 计算区间的异或和。
时间复杂度 。
100%
注意到计算两个数的异或结果 时,二进制下的每一位是独立的。
这意味着如果只看二进制下第 位, 和 不一样,那么 在二进制下第 位为 。
因此我们只需要维护 表示 中有多少项在二进制下第 位上是 。
枚举右端点 ,再枚举二进制下第 位,根据 在这一位上是 还是 ,答案增加 或 。
记 的最大值为 。
时间复杂度 。
T6
10%
将 个路口都保留。
由于路口的转向限制,需要把每个路口拆成 个点对应四个方向。
对于两个距离为 的相邻路口,在拆出来的对应方向的点之间建边,例如:对于两个相邻路口 和 , 在 右侧,那么建一条从 拆出的对应右的点出发,到达从 拆出的对应右的点的有向边。
对于测试点#1,因为 ,用 求出起点到终点的最短距离即可。对于允许转向的路口,还需要考虑转向问题,例如:对于两个相邻路口 和 , 在 右侧且路口 可以转向,那么还要再建 条有向边,分别从 拆出的对应左、上、下的点出发,到达从 拆出的对应右的点。
时间复杂度 。
40%
将 个路口都保留。
对于测试点#2~4,因为 ,所以需要使用 等单源最短路算法来求最短路。
对于同一个路口拆出来的四个点,如果这个路口是允许转向的,在它们之间建边权为 的双向边。
除了拆点后向四个方向建边,还需要在拆出来的点之间建边,所以边的总数规模约为 。
时间复杂度 。
结合第一部分可以拿到 的分数。
60%
对于测试点#5~6, 的范围达到 ,所以只留下起点路口、终点路口、和允许转向的路口作为图上的点,在它们之间建边。
因为 ,所以不需要拆点。
可以用双关键字排序,处理出同一行或同一列的点来建边。注意:每个路口只能和某一方向最近的那个点建边,否则边数有可能达到 。
每个点最多向四个方向的最近点各建一条边,所以边的总数规模约为 。
时间复杂度 。
结合第二部分可以拿到 的分数。
100%
对于 的情况,要把每个路口拆成 个点对应四个方向。
除了拆点后向四个方向建边,还需要在拆出来的点之间建边,所以边的总数规模约为 。
时间复杂度 。