核心概述:在已给定的逆时针凸包上用旋转卡壳在线扫描,O(n) 找到最远点对(凸包直径)。

Description: Returns the two points with max distance on a convex hull (ccw, no duplicate/collinear points). Time: O(n) Status: stress-tested, tested on kattis:roberthood

展开阐述:

  • 定义与背景

    • 凸包直径:凸多边形上两点间的最大欧氏距离,亦称最远点对。常用于形状尺度估计、最小包围矩形的中间过程。
    • 前提:输入为凸包顶点序列,逆时针,且无重复/共线中间点。若尚未构造凸包,先用025-几何-凸包
  • 接口/输入输出(据实现)

    • array<P,2> hullDiameter(vector

      S),P=Point

    • 输出为两端点的数组 {a, b};内部以距离平方比较,避免反复开方。
  • 核心算法流程(Rotating Calipers)

    1. 初始化:令 n=|S|,若 n<2 直接返回;通常从 i=0, j=1 开始。
    2. 对每个 i(0..n-1):
      • 沿对踵点推进 j,使得距离 |S[i]-S[j]| 单调不减。
      • 推进判据:当 (S[(j+1)%n] - S[j]).cross(S[(i+1)%n] - S[i]) > 0 时,j = (j+1)%n。
      • 更新最优:以 dist2 比较并记录最远点对。
    3. 线性复杂度来源:i、j 各至多环绕一圈。
  • 复杂度与边界条件

    • 复杂度:双指针单调推进,总体 O(n)。
    • 小规模与退化:n=1 返回该点与自身(实现可特殊处理);n=2 直接返回两端。
    • 共线:若输入存在共线中间点会影响推进次数与正确性,需保证输入已去除中间点。
  • 实现细节与常见坑

    • 比较使用 dist2(ll 计算可能溢出,必要时用内建 128 位)。
    • 判据使用 >= 或 > 的取舍会影响 j 的停留与推进,需与实现保持一致以避免漏解。
    • 注意索引取模,避免数组越界。
  • 变体与扩展

    • 同步计算最小包围矩形:在卡壳过程中维护与边平行的外接矩形,输出面积最小者。
    • 三维最远点对:可通过旋转卡壳推广但实现复杂度高。
  • 正确性要点与不变式

    • 对踵点性质保证每条支撑线至多对应一个最远方向,双指针总推进次数线性。
    • 凸性与 ccw 顺序是旋转卡壳正确性的关键前提。
  • 对比与取舍

    • 与暴力 O(n^2) 比:显著加速。
    • 与 KD 树等结构:全局最远点对在凸包上,先取025-几何-凸包再卡壳是标准方案。

关联节点