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 range
、for j in range
嵌套。以上是关于Facebook杯回旋镖编程的主要内容,如果未能解决你的问题,请参考以下文章