Facebook杯回旋镖编程

Posted

技术标签:

【中文标题】Facebook杯回旋镖编程【英文标题】:Facebook cup boomerang programming 【发布时间】:2016-01-12 22:09:24 【问题描述】:

我试图解决 Facebook 黑客杯 2016 的资格问题之一,回旋镖星座。 (http://codeforces.com/gym/100869/attachments/download/4028/2016-facebook-hacker-cup-qualification-round-en.pdf)

我的算法是针对每个星点,计算到其他星的距离,并使用 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))

【问题讨论】:

您的代码有一个 3 级嵌套循环(一个在外部代码中,两个在 findBoomerang 中),每个都以星数为界。规则说,一个晚上最多可以有 2000 颗星星。这意味着您的内部循环有 2000*2000*2000 次迭代的最坏情况,这可能是您的算法超过时间限制的原因。 顺便说一句,外部循环看起来不对 - constellations = findBoomerang(stars) 可能应该被削去? @TomDalton 抱歉,外部循环错误。就像你说的,constellations = findBoomerang(stars) 应该被削去(这就是我在提交的代码中所做的,这里只是一个复制粘贴错误)。 @TomDalton 在其中一个测试用例中遇到了时间限制,我认为我们需要排除外部循环,因为那只是用于处理 N 个输入。算法本身需要 O(N^2)。 这里的一个问题来源是使用双精度数据类型的长度,双精度精确到 1e-16 不多,我建议您阅读this 简短说明:所以距离 1.10000000000000001 与 1.10000000000000002 相同在问题中,但是,在语言的内置数据结构中,这一点被省略了,并且可能以不同的距离威胁这个值,在双精度数据类型中,您应该始终使用阈值来检查相等性。 【参考方案1】:

两个小改进。

首先,为您的密钥使用长度平方而不是长度。这消除了 很多 平方根运算。

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

【讨论】:

此外,虽然您避免将星星与自身进行比较,但您仍然在将 A 与 B 以及 B 与 A 进行比较,因为您的 for i in rangefor j in range 嵌套。

以上是关于Facebook杯回旋镖编程的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1037. 有效的回旋镖

447. 回旋镖的数量

1037. 有效的回旋镖

《LeetCode之每日一题》:148.回旋镖的数量

LeetCode 1037.有效的回旋镖:斜率 - 一行解决

Leetcode——回旋镖