如果话题令人困惑,我很抱歉。这是因为我不知道我在寻找什么。我有一组P(|P| < 10^5
)。每个点都有整数坐标(between -10^4, 10^4
)如何找到直线,它遍历输入中指定的所有点。条件是线必须是最粗的,并且您必须输出直线的厚度,精确到小数点后的2位。任何提示,线索,想法或算法名称都会受到赞赏。
PS。这既不是家庭作业也不是SPOJ。我只是通过上一期的问题来准备编程比赛。那个我无法解决的,即使我不知道从哪里开始寻找解决方案......
答案 0 :(得分:1)
您可以先确定此点云的凸包(参见例如http://softsurfer.com/Archive/algorithm_0109/algorithm_0109.htm),然后尝试找到以最短距离约束此多边形的两条平行线。
我认为这应该是一个更容易解决的问题,因为它允许您将凸起船体的部分(其数量有限)的平行线方向作为基础。
一种实施方式可以依次处理凸包的每个部分。每段,通过它绘制一条直线(这是两条平行线中的一条),然后确定包围凸包的最近的另一条平行线。对凸包的每个部分执行此操作,同时记录到目前为止在平行线之间找到的最小距离。最后,你应该得到最佳结果。
显然,这仍然需要一种有效的方法来确定最接近的其他平行线。一个(天真的,但也许是足够好的)这样做的方法是获取不在当前段上的凸包的所有顶点,并确定通过它的直线的垂直距离(例如http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line)。所有这些顶点的最大距离也是到平行线的最小距离。
在伪代码中:
Function FindThinnestLine(PointCloud P)
CH = ConvexHull(P)
optS = nothing
optDist = infinite
For each segment S in CH
L = the line through S
/* Find the minimum distance that the line parallel to L must have in order to enclose CH */
maxDist = 0
For each vertex P in CH, except the two that limit S
dist = The distance between L and P
maxDist = max(dist, maxDist)
/* If the current S has a smaller maxDist, it is our new optimum */
if(maxDist < optDist)
optS = S
optDist = maxDist
Return the line through optS and the line parallel to optS at a distance of optDist as the result
End Function
这是一个O(n ^ 2)算法,n是凸包中的段数。
修改强>
想想看,你不需要为每个S迭代凸包的O(n)个顶点(为了找到maxDist),只为第一个 S迭代。让我们说我们称之为第一个顶点oppV( opp 与S相反),并且假设我们按顺时针顺序处理凸包的各个部分。对于我们处理的每个后续S,新的oppV可以是相同的顶点,也可以是其右边界之一(但绝不是左邻居,否则这些段不会形成凸多边形)。
因此,处理凸包的段然后可以在O(n)中完成(但是创建凸包仍然是O(n log n))。
答案 1 :(得分:0)
包含P的给定子集的所有点的最粗线应该是段xy
的垂直平分线,其中x
和y
是子集的两个点,其中highest distance d
他们之间。这条线的粗细也是d
。