内有N个点的三角形数

时间:2016-12-18 15:22:56

标签: math geometry computational-geometry combinatorics triangle-count

给定平面中的一些点(高达500点),没有3个共线。我们必须确定顶点来自给定点并且其中包含正好N个点的三角形的数量。如何有效地解决这个问题?天真的O(n ^ 4)算法太慢了。有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以尝试将三角形视为三个半空间的交集。为了找到三角形A,B,C内的点数,首先考虑AB方向上无限线一侧的点集。让这些设置L(AB)和R(AB)用于左和右的点。类似地,与其他两个边相同,构建集L(AC)和R(AC)并设置L(BC)和R(BC)。

因此,ABC中的点数将是L(AB),L(AC)和L(BC)交点中的点数。 (您可能需要考虑R(AB),具体取决于三角形的方向。)

现在,如果我们想要考虑全套500分。首先取所有点对AB并构建集合L(AB)和R(AB)。这将需要O(n ^ 3)次操作。

接下来,我们测试所有三角形并找到三组的交叉点。如果我们为集合使用一些哈希表结构,那么找到交集点就像一个哈希表查找。如果L(AB)具有l个元素,则L(AC)具有m个元素和L(BC)n个元素。说l> m> ñ。对于L(BC)中的每个点,我们需要在L(AC)和L(BC)中进行查找,以便最多进行2n个哈希表查找。

考虑几何查找表可能会更快。 将整个域划分为粗网格,例如10乘10格。然后我们可以将每个点放入集合G(i,j)中。然后我们可以将集合L(AB)分成每个网格单元。比如称这些集合为L(AB,i,j)和R(AB,i,j)。在测试交叉口时,首先锻炼网格单元位于交叉点。这大大减少了搜索空间,并且由于每个集合L(AB,i,j)包含的成员较少,因此散列表查找次数会减少。

答案 1 :(得分:1)

实际上我最近遇到了类似的问题,但唯一的区别是有大约300分,我用bitset(C ++ STL)解决了它。对于每对点,比如说(x [i],y [i])和(x [j],y [j]),我形成了一个bitset< 302> B [i] [j]和B [i] [j] [k]如果第k个点位于从第i点到第j点的线段之上,则存储1,否则我将存储0。

现在以蛮力的方式我得到三个点以便形成一个三角形,让我们说(x [i],y [i]),(x [j],y [j])和(x [k ],y [k]),那么如果B [i] [j] [z] == B [i] [j] [k]&&并且一个点,比如z点,将在三角形内。 B [j] [k] [z] == B [j] [k] [i]&& B [k] [i] [z] == B [k] [i] [j]因为三角形内的点会显示相似的符号w.r.t.三角形的一边作为三角形的第三个点(一个不在这一边)。 所以我得到三个bitset变量P = B [i] [j],Q = B [j] [k]和R = B [k] [i]并且在那里采用按位AND然后应用count()函数给我有效位数,因此三角形内的点数。但是请确保你改变变量P,使得它给出B [i] [j] [k] = 1,如果不是,那么取这个变量的按位(#)。

虽然上述解决方案是特定于问题的,但我希望它有所帮助。这是问题链接:http://usaco.org/current/index.php?page=viewproblem&cpid=660