1 条题解
-
0
好的,我们根据这个代码来分析算法思路并生成题解和标签。
算法思路
这是一个利用对称性统计曼哈顿等边三角形的巧妙方法。
核心观察
在曼哈顿距离下,“等边三角形”实际上是一个等腰直角三角形,直角顶点在中间,两个腰长度相等。
更具体地说:如果三点 两两曼哈顿距离相等,那么它们构成一个“斜 45 度”的正方形的一半。
方法步骤
-
枚举直角顶点 + 斜边方向
对于每个可能的直角顶点 ,考虑它作为直角顶点,两个腰分别向右下和左下延伸长度 ,得到另外两点 和 ,然后检查第三点 是否存在。 -
前缀和优化
定义sum[i][j][k]表示从 向左上走 步(曼哈顿距离)的矩形区域内的牛的数量(实际上是一个菱形区域)。
这样可以在 时间内知道某个菱形区域内是否有牛。 -
四次旋转计算
因为等腰直角三角形的方向有 4 种(对应坐标轴的四个象限方向),所以将网格旋转 4 次,每次计算一种方向。 -
去重
最后一部分的循环是去重:当三点共线时(水平或竖直),会被错误统计,需要减去这些情况。- 如果某行/列上有 3 个点共线且等距,会被错误算作三角形,需要减去。
- 如果 4 个点共线且等距,会形成多个错误统计,需要减去对应数量。
代码流程
-
calc()函数- 三重循环: 枚举直角顶点, 枚举腰长。
- 用动态规划计算
sum[i][j][k]表示左上菱形区域牛的数量。 - 如果 和 有牛,则加上
sum[i][j][k](即第三点 所在菱形区域内的牛数)。
-
四次旋转
- 第一次:原图。
- 第二次:左右翻转。
- 第三次:上下翻转。
- 第四次:左右翻转(回到上下翻转后的左右翻转,即 180 度旋转+?)。
-
去重
- 对每个点 ,统计它所在行和列上与之曼哈顿距离为 的牛的数量
cnt[k]。 - 如果
cnt[k] == 3,说明有 3 个点共线等距,减去 1 个错误统计。 - 如果
cnt[k] == 4,说明有 4 个点共线等距,减去 4 个错误统计(组合数 )。
- 对每个点 ,统计它所在行和列上与之曼哈顿距离为 的牛的数量
复杂度
- 前缀和与统计:
- 四次旋转:常数 4 倍
- 去重:
- 总复杂度:,在 时可接受。
算法标签
#曼哈顿距离 #前缀和 #组合计数 #对称性 #几何
关键点总结
- 曼哈顿等边三角形实际上是等腰直角三角形,且直角顶点在中间。
- 通过枚举直角顶点和腰长,用前缀和快速统计第三点存在的数量。
- 旋转网格处理所有方向。
- 最后要去掉共线情况的错误统计。
-
- 1
信息
- ID
- 5402
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者