Python Facebook杯回飞棒编程

Python Facebook杯回飞棒编程,python,algorithm,Python,Algorithm,我试图解决Facebook hackercup 2016中的一个资格问题,即回飞棒星座。() 我的算法是针对每个星点,计算到其他星点的距离,并使用python字典使用距离键散列其他点 然后我通过计算每个列表的n*(n-1)/2(按距离计算),计算出可能的回飞棒星座 当我运行Facebook提供的输入和输出时,答案是正确的。但当我将此代码提交给codeforces时,它以“超过时间限制”而失败。你能指出代码的哪一部分是无效的吗?这是Python的问题吗 import math def findBo

我试图解决Facebook hackercup 2016中的一个资格问题,即回飞棒星座。()

我的算法是针对每个星点,计算到其他星点的距离,并使用python字典使用距离键散列其他点

然后我通过计算每个列表的n*(n-1)/2(按距离计算),计算出可能的回飞棒星座

当我运行Facebook提供的输入和输出时,答案是正确的。但当我将此代码提交给codeforces时,它以“超过时间限制”而失败。你能指出代码的哪一部分是无效的吗?这是Python的问题吗

import math
def findBoomerang(stars):
sum = 0
N = len(stars)
for i in range(N):
    lines = {}
    for j in range(N):
        if i == j:
            continue
        length = round(distance(stars[i], stars[j]), 3)
        if length not in lines:
            lines[length] = list()
        lines[length].append(stars[j])
    for i in lines.keys():
        n = len(lines[i])
        sum+=(int)(n*(n-1)/2)
return (int)(sum)

def distance(starA, starB):
(x1, y1) = starA
(x2, y2) = starB
return math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))


nights = int(input())
for night in range(nights):
    num_stars = int(input())
    stars = list()
    for i in range(num_stars):
        x,y = [int(x) for x in input().split(" ")]
        stars.append((x,y))
    constellations = findBoomerang(stars)
    print("Case #"+ str(night+1)+ ": "+ str(constellations))

两个小的改进

首先,使用键的长度平方,而不是长度。这将删除许多平方根运算


第二,没有必要列出给定长度的所有恒星。相反,您可以只计算它们。

您的代码有一个三级嵌套循环(一个在外部代码中,两个在findBoomerang中),每个循环都以星星数为边界。规则说一个晚上可能有多达2000颗星星。这意味着您的最坏情况是内部循环的2000*2000*2000次迭代,这可能是您的算法超出时间限制的原因。顺便说一句,外部循环看起来是错误的-
constellations=findBoomerang(stars)
可能应该被删除?@TomDalton抱歉,外部循环是错误的。正如你所说的,constellations=findBoomerang(stars)应该被删除(这就是我在提交的代码中所做的,这里只是一个复制粘贴错误)。@TomDalton时间限制在一个测试用例中被捕获,我认为我们需要排除外循环,因为这只是为了处理N个输入。算法本身需要O(N^2)。这里的一个问题是使用双精度数据类型表示长度,双精度精确到1e-16,而不是更多,我建议您阅读简短的解释:因此,距离1.100000000000001与问题中的1.100000000000002相同,但是,在语言的内置数据结构中,这一点被忽略,并且可能会威胁到该值,因为距离不同,在双数据类型中,您应该始终使用阈值来检查相等性。此外,虽然您避免将星与自身进行比较,但您仍然将a与B和B与a进行比较,因为您的
用于范围内的i
用于范围内的j
嵌套。