找到等腰直角三角形的重量值

时间:2016-03-11 18:52:37

标签: algorithm combinations permutation dynamic-programming

我想找出n * m矩形网格内等腰直角三角形总数的权重值。权重值是在矩形网格中添加每个点值的总和的值。让我通过一个例子来解释

enter image description here

这是矩形网格,n = 1,m = 2。我想找出这个网格中存在的每个等腰直角三角形的重量。这里是可能的直角等腰三角形,它可以由这个网格形成

enter image description here

所以我想找出每个三角形的权重值,如三角形A有4,B有6。 我尝试使用C Program to detect right angled triangles找到直角三角形的总数,但如果我只知道有多少个三角形,则很难找到每个三角形的重量。我解决这个问题的方法是挑选每个点并找到与之相关的三角形和相应的权重值。但它需要时间复杂度的4倍于网格中的点数(在这种情况下为4 * 2 * 3)。我想找到一个有效的公式,这样我就可以对大n和m执行此操作。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

根据评论中的讨论,您希望枚举所有可能的三角形并发现边缘上所有点的总和。

您可以按如下方式枚举三角形。给定一个点p = (p1, p2)和另一个点q = (q1, q2),只有一个直角等腰从p开始,转到q并向右转。第三个顶点位于r = (q1 + q2 - p2, q2 - q1 + p1)。如果你遍历所有顶点对,这将只找到每个可能的三角形。

接下来我们需要每个线段的权重。给定从pq的线段,首先找到(q1 - p1, q2 - p2)的GCD。 (特殊情况。任何整数的GCD和0都是1.)然后用该GCD将两个系数除以得到沿着该点从一点到另一点的最小向量。我们称之为最小的向量v。现在,您可以为p, p+v, p+2v, ...添加权重,然后在q处停止。 (注意,每个行间隔应包括一个点,而不是另一个。)

你去吧。最终算法应为O(n^2 m^2 log(n+m))。鉴于直角等腰三角形的数量为O(n^2 m^2),这不能得到很大改善。如果需要,您可以通过递归(starting point, unit vector, n)的权重然后记住它来改进日志因子。然而,这需要O(n^2 m^2)数据结构,并且解决它的局部性问题可能很容易超过理论性能增益。

好的,改进!而不是迭代成对的点,迭代起始向量v = (v1, v2)(v1, v2)相对素数(检查欧几里德算法,然后检查起点p = (p1, p2),然后超过倍数i您正在考虑的三角形将是(p1, p2), (p1 + n*v1, p2 + n*v2), (p1 + n*v1 + n*v2, p2 - n*v1 + n*v2)。现在,对于每个起始向量,p2 - p1的每个值以及您可能要去的3个方向中的每一个,您都可以计算出从无穷大到该行上每个点的所有权重的总和。(一个O(nm)数据结构。)使用该数据结构,两个内部循环可以按时间O(1)每个三角形执行。 / p>

这会为您提供O(n^2 m^2)算法,以查找所有O(n^2 * m^2)直角等腰三角形的总重量。这在理论上和你一样好。 (所需的辅助数据结构为O(nm)。)