【问题标题】:C Program to detect right angled triangles检测直角三角形的C程序
【发布时间】:2014-10-07 22:51:33
【问题描述】:

如果给定坐标系中的 100 个点,我必须找出这些顶点中是否存在直角三角形。 有没有一种方法可以检测这些顶点之间的直角三角形,而不必选择所有 3 个顶点对然后在它们上应用毕达哥拉斯定理? 有没有更好的算法来解决这个问题? 谢谢你的帮助。 :)

【问题讨论】:

  • 您可以找到所有点对 (p1 - p2) 的向量,然后检查其中 2 个向量(具有一个共同端点)的点积结果为零。
  • 但是如果我有 100 分,那么获取 2 分的每一个可能的子集不会是一项更耗时的任务吗??
  • 100 分并不多。实现朴素算法就好了,反正不会花太长时间。
  • 100 个点生成 9900 个向量。对于每个向量,您最多需要考虑 98 个其他向量。总共不到 1,000,000 个点积。如果你很聪明,你可以用少于 500,000 个点积来做到这一点。这是完全可行的。
  • 你不会碰巧只在二维中工作吧?

标签: c algorithm


【解决方案1】:

这是一个O(n^2 log n)-time算法,仅适用于二维。我将描述在更高维度中出了什么问题。

令 S 为点的集合,具有整数坐标。对于 S 中的每个点 o,构造一组非零向量 V(o) = {p - o | p in S - {o}} 并测试 V(o) 是否在线性时间内包含两个正交向量,如下所示。

方法一:将每个向量(x, y)规范化为(x/gcd(x, y), y/gcd(x, y)),其中|gcd(x, y)|是除 x 和 y 的最大整数,如果 y 为负,则 gcd(x, y) 为负,如果 y 为正,则为正,|x|如果 y 为零。 (这与将分数放在最低限度非常相似。)关于二维的关键事实是,对于每个非零向量,恰好存在一个与该向量正交的规范向量,特别是 (-y, x) 的规范化.将 V(o) 中每个向量的规范化插入到集合数据结构中,然后对于 V(o) 中的每个向量,在该数据结构中查找其规范正交配对。我假设 gcd 和/或 set 操作需要时间 O(log n)。

方法2:在向量上定义一个比较器,如下所示。给定向量(a, b), (c, d),写(a, b) < (c, d)当且仅当

s1 s2 (a d - b c) < 0,

在哪里

s1 = -1 if b < 0 or (b == 0 and a < 0)
      1 otherwise
s2 = -1 if d < 0 or (d == 0 and c < 0)
      1 otherwise.

使用此比较器对向量进行排序。 (这与比较分数 a/bc/d 非常相似。)对于 V(o) 中的每个向量 (x, y),对其正交配对 (-y, x) 进行二分搜索。

在三个维度上,与沿 z 轴的单位向量正交的向量集是整个 x-y 平面,而等价的规范化无法将这个平面中的所有向量映射到一个正交配对。

【讨论】:

  • 非常感谢您对它进行调查,先生。但是你能再解释一下规范化的事情吗?像册封有什么用? (除以 gcd(x,y))?此外,我有n 点,然后形成选择所有其他点的向量将是 O(n^2) 对吗?然后检查为正交属性形成的所有其他向量将是 O(n) (线性查看所有向量?)所以,它将是 O(n^2),不是吗?怎么会是O(n^2logn)??请解释..谢谢.. :)
  • @user007 这就像把一个分数至少放在一起。如果我们假设 gcd 是恒定时间并且我们可以访问哈希集,那么是的,运行时间将是 O(n^2)。
  • 更简单:对于每个点,按角度对其他点进行排序,然后在 O(n) 中查找是否有两个正交。总体而言,O(n^2.log(n)) 与您的解决方案相同。
  • @Anonymous 如果您相信您的atan2 不会发生虚假冲突,那么可以肯定。问题是,例如,atan2(pow(2, 31) - 1, 1) == atan2(pow(2, 31) - 2, 1) 与 IEEE 双打。第二个比较器使用整数运算按角度排序。
猜你喜欢
  • 2020-10-06
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
相关资源
最近更新 更多