我正在尝试解决编程挑战并且仅仅部分地成功完成了这项工作;我需要优化解决方案 - 这就是你进来的地方。首先,参数:
int x1, y1, x2, y2
。int px, py = INT_MAX
。px, py
直线向下“下降”(较小的y值)
px
。所以,我想:
int xtop, ytop, xbot, ybot
,ybot
排序。这允许我们跳过球已经过去的线,imin
,使所有lines[i].ybot >= py
i < imin
,然后直到找不到交叉:
yi = kx + m
,px, py = lines[i].{x, y}bot
。问题在于这个时间复杂度∈θ(n 2 ) - IOW,对于大输入来说很糟糕。
一个想法是使用类似k-d tree的东西,但问题是如果计算哪些线进入所谓的半空间是不是非常昂贵。
答案 0 :(得分:0)
听起来好像你对point location in a planar subdivision感兴趣。我链接的slab分解方法是一个更简单的选项;简而言之,您从一个线段的每个端点延伸垂直线,使2n + 1个垂直板。对于每个板,您计算一个二叉树,从上到下指示哪些段穿过板。然后,为了找到球击中的位置,确定它所在的哪个板块然后击中哪个段(如果有的话);这两个操作都是O(log n)-time。
要首先计算二叉树,请使用扫描线算法。从空二进制树开始,按x坐标的排序顺序处理端点。对于左端点,将段插入树中。对于右侧,将其从树中删除。假设段不交叉,则永远不需要在树中重新排序。天真地,我们必须在每一步之后复制树,但是从O(n ^ 2)将存储降低到O(n log n)的简单策略是使用纯功能的红黑树,从而无需副本。
此方法的总运行时间和空间为O(n log n)。