Algorithm 找到由点集形成的三角形是否包含原点并给出总计数的算法?
输入:Algorithm 找到由点集形成的三角形是否包含原点并给出总计数的算法?,algorithm,Algorithm,输入:S={p1,…,pn},n二维平面上的点每个点由其x和y坐标给出 为简单起见,我们假设: 原点(0,0)不在S中。 通过(0,0)的任何线L在S中最多包含一个点。 S中没有三个点位于同一条线上。 如果我们从S中选择任意三个点,我们可以形成一个三角形。所以用这种方法形成的三角形的总数是Θ(n^3) 有些三角形包含(0,0),有些不包含 问题:计算包含(0,0)的三角形数 你可以假设我们有一个O(1)时间函数Test(pi,pj,pk)如果由{pi,pj,pk}构成的三角形包含(0,0),那
S={p1,…,pn}
,n
二维平面上的点每个点由其x和y坐标给出
为简单起见,我们假设:
原点(0,0)不在S中。
通过(0,0)的任何线L在S中最多包含一个点。
S中没有三个点位于同一条线上。
如果我们从S中选择任意三个点,我们可以形成一个三角形。所以用这种方法形成的三角形的总数是Θ(n^3)
有些三角形包含(0,0),有些不包含
问题:计算包含(0,0)的三角形数
你可以假设我们有一个O(1)时间函数Test(pi,pj,pk)
如果由{pi,pj,pk}
构成的三角形包含(0,0),那么给定S中的三个点pi,pj,pk,返回1,否则返回0。在Θ(n^3)时间内解决问题很简单(只需枚举并测试所有三角形)
描述一个用O(n logn)运行时解决这个问题的算法
我对上述问题的分析得出以下结论 有4个坐标(+、+)、(+、-)、(-)、(-)、(-){x和y坐标>0或不>0} 让
- s1=坐标x<0和y>0
- s2=x>0,y>0
- s3=x<0,y<0
- s4=x>0,y<0
在最坏的情况下,似乎存在包含原点的Θ(n3)三角形,因为您需要它们,答案是否定的,没有更好的算法
对于最坏的情况,考虑奇数度的正多边形<代码> N< /代码>,以原点为中心。
下面是计算的概要。连接两个相隔
k
顶点的弦是Θ(k)三角形的基础。固定一个顶点;它的贡献是来自它的所有和弦的总和,产生Θ(n2),总的贡献(所有n
顶点的贡献)是Θ(n3)(每个三角形计算3次,这不影响渐近性)。我猜我们属于同一类(基于问题的奇怪措辞),所以现在到期日已经过去了,我觉得给出我的解决方案没问题。我设法找到了nlogn算法,正如问题所述,这更像是一个巧妙地转换问题的问题,而不是一个动态规划/DaC解决方案
注意:这不是一个详尽的证据,我把它留给你。
首先,一些视觉观察。取一个明显包含原点的三角形 然后,将点转换为向量 让自己相信,任何三个点的选择,每个向量一个,都描述了一个同样包含原点的三角形 同样,如果在不包含原点的三角形上执行上述步骤,则沿这些向量的任何点组合也不会包含原点 由此得出的要点是,向量的大小不重要,只影响方向。此外,问题的提示是“任何直线交叉(0,0)只包含S中的一个点”,由此我们可以推断每个向量的方向是唯一的。
因此,如果只有角度是重要的,那么就会有一些逻辑来确定给定两点的点的范围可能形成一个包围原点的三角形。为简单起见,我们假设取了S中的所有点,并将它们转换为向量,然后对它们进行归一化,有效地使所有点位于单位圆上 沿着这个圆取两点 然后,从每个点通过原点到圆的另一侧绘制一条线 因此,给定这两个点,沿红色圆弧的任何点都可以形成三角形
因此,我们的算法应该执行以下操作:
int triangleCount(point P[],int n)
int A[n], C[n], totalCount = 0;
for(i=0...n)
A[i] = atan2(P[i].x,P[i].y);
mergeSort(A);
int midPoint = binarySearch(A,π);
for(i=0...midPoint-1)
int left = A[i] + π, right = A[i+1] + π;
C[i] = binarySearch(a,right) - binarySearch(a,left);
for(j=0...i)
totalCount += C[j]
return totalCount;