现在我正在尝试解决Project Euler 71。
考虑分数,n / d,其中n和d是正整数。如果 ñ
如果我们列出d≤8的递减的适当分数的集合 大小顺序,我们得到:
1 / 8,1 / 7,1 / 6,1 / 5,1 / 4,2 / 7,1 / 3,3 / 8,2 / 5,3 / 7,1 / 2,3 / 7 ,3 / 5,5 / 8, 2 / 3,5 / 7,3 / 4,4 / 5,5 / 6,6 / 7,7 / 8
可以看出2/5是紧接在左边的部分 3/7。
列出d≤1,000,000in的减少适当分数的集合 大小的升序,找到分数的分子 紧靠3/7左侧。
from fractions import Fraction
import math
n = 428572
d = 1000000
x = Fraction(3,7)
best = Fraction(0)
while d > 1:
if Fraction(n,d) >= x:
n-=1
else:
y = Fraction(n,d)
if (x - y) < (x - best):
best = y
d -= 1
n = int(math.ceil(d*0.428572))
print(best.denominator)
from fractions import Fraction
import math
需要分数和math.ceil。
n = 428572
d = 1000000
这两个变量代表原始问题中陈述的n
和d
。数字以这种方式开头,因为这是3/7
稍微大一点的表示(稍后会转换为Fraction)。
x = Fraction(3,7)
best = Fraction(0)
x只是Fraction(3,7)
的快速参考,所以我不必继续输入它。 best
用于跟踪最接近3/7
但仍然离开的分数。
while d > 1:
如果d <= 1
和n
必须小于1
,检查的重点是什么?然后停止检查。
if Fraction(n,d) >= x:
n-=1
如果分数最终大于或等于3/7
,则它不在其左侧,因此请保持从n
减去直至3/7
的左侧
else:
y = Fraction(n,d)
if (x - y) < (x - best):
best = y
如果它位于3/7
的左侧,请查看3/7
减去best
或y
(等于我们需要检查的分数)是否接近0接近零的那个将是最左边的,或最接近3/7
。
d -= 1
n = int(math.ceil(d*0.428572))
无论是否有最佳变化,分母都需要改变。因此,从分母中减去一个,并将分数(n,d)稍微大一些(添加额外的ceil方法以确保它更大!),而不是3/7
来修剪测试空间。
print(best.denominator)
最后打印出问题的内容。
将d
更改为8
,将n
更改为4
(与测试用例一样),可为分母提供所需的5
结果。保持原样:999997
。
有人可以向我解释我做错了吗?
答案 0 :(得分:4)
这是正确的做事方式。你应该使用the Stern-Brocot tree。你根本不应该搞乱浮点。
答案 1 :(得分:2)
你做错了什么:
找到分子
除此之外,请遵循@ Antimony的建议,了解Stern-Brocot树,这是有用和有趣的。
答案 2 :(得分:1)
不要让你感到愚蠢。但你的答案是完全正确的,再次阅读问题并将最后一行更改为:
print( best.numerator )
另外,为了记录,有一种 MUCH 更有效的计算方法。