Project Euler problem 9 勾股数

这题还有点意思


找出一组勾股数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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值