1 条题解
-
0
题解
问题分析
题目要求用最少的防御塔覆盖整个矩形城池(左下角,右上角)。防御塔分为4个方向,覆盖不同的无限矩形区域:
- 方向1(RU):覆盖(右上区域)
- 方向2(LU):覆盖(左上区域)
- 方向3(LD):覆盖(左下区域)
- 方向4(RD):覆盖(右下区域)
核心挑战是找到最少的防御塔组合,使得城池内所有点均被至少一个塔覆盖。
关键洞察
- 覆盖的互补性:单个方向的塔无法覆盖整个城池,需组合不同方向的塔(如RU与LD、LU与RD)形成互补覆盖。
- 最优塔的选择:同一方向的塔中,存在“最优塔”——其覆盖范围最大。例如,RU塔中,固定时越小,覆盖的右上区域越大。
- 对称性:4个方向存在旋转对称性(通过交换、翻转坐标可将一个方向转化为另一个),可通过旋转变换复用逻辑处理所有方向组合。
- 依赖关系:部分塔的覆盖需要其他塔的配合,可通过图建模这种依赖,用DFS计算最少塔数。
算法步骤
-
预处理最优防御塔:
针对每个方向,筛选出覆盖范围最大的塔,并通过前缀/后缀优化快速查询:- LU塔(方向2):用
yl[x]记录处最小的(越小,覆盖的左上区域越大),并做后缀优化(从右到左取最小值)。 - RD塔(方向4):用
yr[x]记录处最大的(越大,覆盖的右下区域越大),并做前缀优化(从左到右取最大值)。 - RU塔(方向1):用
pd[x]记录处最小的塔(越小越好),并做前缀优化。 - LD塔(方向3):用
pr[y]记录处最大的塔(越大越好),并做后缀优化。
- LU塔(方向2):用
-
构建依赖关系图:
分析RU与LD塔的配合关系:若RU塔和LD塔能共同覆盖部分区域,则直接标记的最少塔数为2;否则建立从到的边(表示依赖)。通过DFS遍历图,更新每个塔所需的最少塔数(f数组)。 -
对称性处理:
对城池进行4次旋转变换(交换、翻转坐标、调整方向),每次变换后复用Work函数的逻辑,处理所有可能的方向组合,确保覆盖所有互补情况。 -
结果计算:
从4次变换的结果中取最小值,若仍为无穷大则输出“Impossible”,否则输出最少塔数。
代码解析
- 快速读入:
FastRead模块处理大规模输入,提高效率。 - 预处理数组:
yl、yr、pd、pr分别存储各方向最优塔的信息,前缀/后缀优化使其支持查询。 - 图与DFS:
Add函数构建塔之间的依赖边,DFS通过遍历依赖关系更新f数组(记录覆盖所需的最少塔数)。 - 旋转变换:
Solve函数中4次循环通过坐标变换(swap(x,y)、x = n - x + 1)和方向调整(d = (d & 3) + 1),复用Work函数处理所有对称情况。 - 结果整合:最终
ans取4次变换的最小值,加2(基础组合的塔数)后输出,若无法覆盖则输出“Impossible”。
复杂度分析
- 时间复杂度:,其中为测试组数,为防御塔数量。预处理、图构建和DFS均为线性操作,4次旋转变换不增加额外复杂度。
- 空间复杂度:,用于存储预处理数组、图的边和中间结果(
f、la等)。
综上,算法通过贪心选择最优塔、利用对称性减少计算量、结合图论处理依赖关系,高效求解了最少防御塔覆盖问题,适用于大规模输入。
- 1
信息
- ID
- 4677
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者