Project Euler 39: 整数直角三角形(integer right triangles)

如果$p$是一个整数边$\{a,b,c\}$的直角三角形的周长,对于$p=120$仅有三个符合要求的解:

$$ \{20,48,52\},\{24,45,51\},\{30,40,50\} $$

求使得符合要求的解的数量最大的$p$值,其中$p\le1000$。

分析:此题的解题思路相对直接,据题意我们有$a+b+c=p$,则$c=p-a-b$,则有:

$$ a^2+b^2=c^2=(p-a-b)^2=p^2+a^2+b^2-2pa-2pb+2ab $$

则可以得到:

$$ b=(p^2-2pa)/(2p-2a) $$

则所有使得$b$为整数的$p$与$a$都可以满足题目的要求,从而可以得到一组符合要求勾股三元数。此外,不失一般性,我们假设$a\le b

题目要求$p\le 1000$时满足条件的勾股三元数对最多的$p$值,则我们只需要把不同的$p$代入上面的函数,算出对应的勾股数对的数量,最后统计勾股数对最多的对应周长即可。但考虑到题目的性质,我们可以对需要筛选的$p$值范围再做精减,假设:

  • $a$与$b$都是偶数,则$c$也为偶数,则$p$为偶数;
  • $a$与$b$一奇一偶,则$c$为奇数,则$p$为偶数;
  • $a$与$b$都为奇数,则$c$为偶数,则$p$为偶数。

据此,我们可以得出结论:$p$必然为一个偶数,则我们只需要筛选1000以下的所有偶数周长即可,缩小了一半的筛选范围。

def number_of_solution(p):
    num = 0
    for a in range(1,p//3):
        if (p**2-2*p*a)%(2*p-2*a) == 0:
            num += 1
    return num

def main(n=1000):
    d = {p:number_of_solution(p) for p in range(2,n+1,2)}
    ans = max(d,key=d.get)
    return ans

你可能感兴趣的:(python,算法)