您的位置:首页 > 其它

Project Euler problem 9 勾股数

2012-11-02 23:58 337 查看
这题还有点意思

找出一组勾股数a,b,c使得a + b+ c = 1000

最后求a * b * c是多少

最裸的想法是1000 * 1000的枚举

不过,显然我们需要更优的算法。

对于a + b + c = s 如果s 比较大怎么办

一个基本勾股数有这样的性质 gcd(a, b, c) = 1

而对所有的勾股数有gcd(a, b) = gcd(a, c) = gcd(b, c)

有一个构造基本勾股数的方法

a = m^ 2 - n ^ 2, b = 2 * m * n, c = m ^ 2 + n ^ 2

m > n > 0

其中m,n的奇偶性必须不同,并且gcd(m, n) = 1

否则带入就可以约掉一个数,就不是基本勾股数了

那么所有的勾股数都可以表示为

a =( m^ 2 - n ^ 2) * d, b = (2 * m * n) * d, c = (m ^ 2 + n ^ 2) * d

a + b + c = 2 * m * (m + n) * d

即s = 2 * m * (m + n) * d

s/ 2= m * (m + n) * d

其中(m + n)必然是奇数

令k = m + n 则 m < k < 2 * m

现在就是枚举s/2的因子了。。。注意上限是sqrt(s/2)向上取整 -1 因为 m < m + n

然后令m等于枚举的因子后, (m + n) * d就算出来了

然后就枚举k满足m < k < 2 *m 并且k <= s/ 2 / m中的所有奇数了

然后就算出来了。

s2 := s div 2

mlimit := ceil(sqrt(s2)) - 1

for m := 2 to mlimit

if s2 mod m = 0 then

sm := s2 div m

while sm mod 2 = 0 // reduce the search space by

sm := sm div 2 // removing all factors 2

end while

if m mod 2 = 1 then k := m+2 else k := m+1

while k < 2*m and k <= sm

if sm mod k = 0 and gcd(k,m) = 1 then

d := s2 div (k*m)

n := k-m

a := d*(m*m-n*n)

b := 2*d*m*n

c := d*(m*m+n*n)

output (a,b,c)

end if

k := k+2

end while

end if

end for
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: