这题还有点意思
找出一组勾股数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