- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
输入:S = {p1, . . . , pn}
, n
二维平面上的点 每个点由其 x 和 y 坐标给出。
为简单起见,我们假设:
原点 (0, 0) 不在 S 中。
如果我们从 S 中任意取三个点,我们就可以组成一个三角形。所以这样可以组成的三角形总数是Θ(n^3)。
通过 (0, 0) 的任何直线 L 至多包含 S 中的一个点。
S 中没有三个点在同一条直线上。
有些三角形包含 (0, 0),有些不包含。
问题:计算包含(0, 0)的三角形的个数。
您可以假设我们有一个时间复杂度为 O(1) 的函数 Test(pi, pj , pk)
给定 S 中的三个点 pi, pj , pk,如果三角形形成,则返回 1 by {pi, pj , pk}
包含 (0, 0),否则返回 0。在 Θ(n^3) 时间内解决问题是微不足道的(只需枚举并测试所有三角形)。
描述一个用 O(n log n) 运行时间解决这个问题的算法。
我对上述问题的分析得出以下结论
有4个坐标(+,+),(+,-),(-,-),(-,+){x和y坐标是否>0}。
让
现在我们只需要对以下组合之间的点进行测试
我现在只需要测试上述集合组合中的点(例如来自 s1 的一个点,来自 s2 的一个点和来自 s3
有人可以指导我吗?
下面添加的图片用于说明为什么只有一些子集 (s1,s2, s4) 可以包含 (0,0) 而有些 (s1,s1,s3) 不能。
最佳答案
我猜我们在同一个类(class)(基于问题的奇怪措辞),所以既然截止日期已经过去,我觉得可以给出我的解决方案。我设法找到了 n log n 算法,正如问题所述,它更多的是巧妙地转换问题,而不是动态编程/DaC 解决方案。
注意:这不是详尽的证明,我把它留给你。
首先,一些视觉观察。取一些明显包含原点的三角形。
然后,将点转换为向量。
说服自己,任意选择三个点,每个点取一个向量,描述一个也包含原点的三角形。
此外,如果您在不包含原点的三角形上执行上述步骤,则沿这些向量的点的任何组合也不包含原点。
从这里得到的要点是,矢量的大小无关紧要,重要的是方向。此外,对问题的提示说“任何线交叉(0 ,0) 只包含 S 中的一个点”,由此我们可以推断出每个向量的方向都是唯一的。
因此,如果只有角度很重要,那么可以得出一些逻辑来确定点的范围,给定两个点,可能形成一个包含原点的三角形。为简单起见,我们假设我们已获取 S 中的所有点并将它们转换为向量,然后对它们进行归一化,有效地使所有点位于单位圆上。
所以,沿着这个圆圈取两点。
然后,从每个点通过原点画一条线到圆的另一边。
由此得出,给定这两个点,任何位于红色圆弧上的点都可以形成一个三角形。
因此我们的算法应该执行以下操作:
取 S 中的每个点。制作一个二级数组 A,并且对于每个点,将沿单位圆 (atan2(x,y)) 的角度添加到 A (0 ≤ Ai ≤ 2π)。我们假设这是 O(n)
按递增方式对 A 排序。 O(n log n),假设我们使用合并排序。
计算每对 (Ai,Aj) 可能出现的三角形数量。这意味着我们计算 Ai + π ≤ Ak ≤ Aj + π 的数量。由于数组已排序,我们可以使用二进制搜索来查找 Ai + π 和 Aj + π 的索引,即 O(2 log n) = O(log n)
但是,我们遇到了一个问题,有 n^2 个点,如果我们必须对每个点进行 O(log n) 搜索,我们有 O(n^ 2 log n)。所以,我们需要再做一个观察。
给定一些 Ai < Aj,我们会说 Tij 描述了可能的三角形数,如上述方法所计算的那样。然后,给定第三个 Ak > Aj,我们知道 Tij ≤ Tik,因为 Ai + π 和 Ak + π 之间的点数必须至少与 Ai + π 和 Aj + π 之间的点数一样多。事实上,它就是 Ai + π 和 Aj + π 之间的计数,加上 Aj + π 和 Ak + π 之间的计数。由于我们已经知道 Ai + π 和 Aj + π 之间的计数,因此我们不需要重新计算它 - 我们只需要计算 Aj + π 和 Ak + π 之间的数,然后加上之前的计数。它遵循:
A(n) = count(A(n),A(n-1)) + count(A(n-1),A(n-2)) + ... + count(A(1) ,A(0))
这意味着我们不需要检查所有 n^2 对,我们只需要检查连续的对 - 所以,只有 n-1。
因此,以上所有可以为我们提供以下伪代码解决方案。
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;
关于查找由点集形成的三角形是否包含原点并给出总数的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33293828/
我在使用带有 vector STL 的迭代器时遇到了这个错误。 代码:- #include #include void print_vec(std::vector vec) { auto
JAVA:两个引用“p”&&“pp”之间有区别吗? PrintStream p = new PrintStream(System.out); p.println("lol");
我尝试从主分支中拉出,但收到错误消息: $ git --no-optional-locks -c color.branch=false -c color.diff=false -c color.sta
我面临着一个让我抓狂的问题! 我有一个函数,这个: void load_weapons3(t_env *e, char *name, int x, t_weapon *w) { char
我正在尝试使用 CUDA 中的最小值、最大值、总和和平均值实现并行归约。 这是我目前的主要代码片段。 int main() { const auto count = 8; const
我知道 double free 或 corruption 错误通常是对 big 3 的违规,但在这种情况下,我找不到违规发生的地方。我有一个复制构造函数、析构函数和赋值运算符,适用于任何处理指针的东西
GTK+ 中的“focus”和“focus-in(out)-event”信号有什么区别?哪个先发射?它们与键盘(TAB)和鼠标点击有什么关系。他们互相依赖吗? 我问这个是因为我想在顶层窗口中跟踪当前聚
*** glibc detected *** /home/ghoshs/workspace/Simulator/Debug/Simulator: double free or corruption (
#include #include #include #include using namespace std; #define MAX_WEIGHT 1000000 class Set {
我在服务器上有两个分支一个叫 R2 的分支和一个叫 DEV 的分支我无意中登录了错误的服务器,进入了存储库并执行了GIT pull 源开发但是存储库在 R2 上。所以我意识到我的错误然后尝试通过做一个
我有一个包含循环的大约 1000 个顶点和 3000 个边的有向图。 我试图从给定的顶点找到所有下游(出)路径。 使用以下 Gremlin 查询时 g.V(45712).repeat(out().si
使用 Delphi XE 2 我试图确定缩放方向以将缩放效果应用于图像(TImage),但没有找到执行此操作的函数,并且图像的 OnGesture 事件中的 EventInfo 属性没有此信息. 我见
我正在尝试创建一个 Zoom_image 函数,它使用离散傅里叶变换来缩放灰度图像。如果图像大小小于或等于 4*4 但大小增加,我包含的代码可以工作。它给出“双重释放或损坏(出)中止(核心转储)”错误
当我执行 popAll 函数时,出现以下错误: 双重释放或腐败(出)中止(核心转储) 我想我已经将错误来源缩小到了这个函数。 IntegerStack 是我制作的一个简单的 ADT,其中包含一个名为
我有网络开发背景,我正在尝试创建类似于 this technique 的东西适用于 iOS(使用 Cocoa/Obj C)。我在谷歌搜索资源时遇到了很多困难,因为 iOS 中的“视差”往往指的是 iO
我想实现一个 faceted search对于我的一个项目。我正在使用 PHP5、Mysql 和 Symfony 1.4。显然社区指向Apache Solr这似乎正是我想要完成的。 问题是该网站将在不
我知道有 questions floating around当您没有提供明确的分支名称时,关于来自特定分支的 git pull,但是我想知道即使用户确实指定了不同的分支,是否也可以强制 pull 分支
我正在尝试将我的更改推送到 NAS 上的存储库。它以我无法理解的方式失败。 documentation声明默认情况下 push 仅适用于快进更新。很公平。所以我做了一个 git pull(我的 Rem
我刚开始使用 Oracle 的 Coherence 缓存,我注意到这一点:如果我在缓存中放入一个 ConcurrentHashMap 对象,当我检索它时,我可以看到它被转换为一个普通的 HashMap
我尝试创建一个连接到数据库的线程,从那里获取一些数据并打印到控制台。问题是当该线程完成时抛出异常: 双重免费或腐败(出局)中止(核心转储) 我尝试使用 sqlite3 和 pthread,但这两个并不
我是一名优秀的程序员,十分优秀!