给定一个hypoteneuse(c
典型方程a*a + b*b = c*c
),计算a
和b
的所有可能整数值的有效方法是什么,{ {1}}?
注意:我看到a < b
大于c
,因此1e12
大于c*c
,我可以告诉long.MaxValue
但是,适合c*c
。
答案 0 :(得分:7)
所有毕达哥拉斯三元组(a,b,c)满足某些整数k,m和n的性质,
a = k(m ^ 2-n ^ 2),b = 2kmn,c = k(m ^ 2 + n ^ 2)
首先考虑因素c。然后,对于c的每个不同因子k(即,对于因子的每个不同子集,乘以一起),找到满足c / k =(m ^ 2 + n ^ 2)的所有m和n。做后者将比其他人建议的蛮力方法花费更少的时间(你只需找到总和为c / k而不是c ^ 2的方格),但会识别所有三元组(a,b,c) 。您也不需要使用bignums,因为所有中间结果都适合长。
我还建议你查看“更通用的毕达哥拉斯三重计算器”标题下的网页http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Pythag/pythag.html,其中包含一个用javascript编写的嵌入式计算器,它正是你想要的。
答案 1 :(得分:6)
有一种数学解决方案,即使对于较大的c值,也能快速找到a和b。 不幸的是,事情并非那么简单。我试图给出一个简短的算法解释。我希望它不会太混乱。
由于给出了c并且你正在寻找a和b,你基本上想要解决丢番图问题 形式方程式
n=x^2+y^2,
其中给出了n。 n = c * c是一个正方形并没有多大帮助,因此我正在描述任何n的解。如果n是素数,那么你可以使用 Fermat's theorem,决定你的等式是否可以解决,并使用,正如Moron指出Hermite-Serret算法找到解决方案,如果有的话。
要解决n不是素数的情况,最好使用 Gaussian integers。 (高斯整数只是具有积分系数的复数)。特别注意到x + yi的范数是
N(x+yi) = x^2+y^2.
因此必须找到高斯整数x + yi,其范数为n。 由于范数是乘法的,因此对于n的因子求解该等式然后乘以单个等式的高斯整数就足够了。 让我举个例子。我们要解决
65 = x^2 + y^2.
这相当于找到x,y这样
N(x+yi) = 65
超过高斯整数。我们考虑65 = 5 * 13,然后我们使用费马注意两者 图5和13的实施例可以表示为两个正方形的总和。最后,我们通过使用Hermite-Serret算法的强力发现
N(2+i) = N(1+2i) = ... = 5
N(2+3i) = N(3+2i) = ... = 13
注意,我已经用负系数省略了Gaussion整数2-i,-2 + i等。 这些当然也是解决方案。
因此,我们现在可以将这些解决方案相乘以获得
65 = 5 * 13 = N(2 + i)* N(2 + 3i)= N((2 + i)*(2 + 3i))= N(1 + 8i)
和
65 = 5 * 13 = N(2 + i)* N(3 + 2i)= N((2 + i)*(3 + 2i))= N(4 + 7i)。
因此,人们得到两个解决方案
1*1 + 8*8 = 65
4*4 + 7*7 = 65
其他组合,例如负系数也需要检查。 除了排列和改变标志外,他们不提供新的解决方案。
要计算所有解决方案,还可以添加无需计算c * c的内容。 找到c的因素是必要的。此外,由于a和b都小于c,因此高斯整数的乘积不能用64位整数系数表示。因此,如果小心,64位整数就足以解决问题。当然,使用像Python这样没有这种溢出问题的语言总是更容易。
答案 2 :(得分:0)
不妨去BigNum图书馆。
至于找到a和b的有效方法:
对于b的每个值(从c-1开始并向下直到b * b
答案 3 :(得分:0)
a的值为1,b的值为c。
将c*c - b*b
与a*a
进行比较。如果他们是平等的,你就有了匹配。
根据哪一方面较大而改变a和b,直到它们相同为止。
答案 4 :(得分:0)
给出一个c:
因为b> a,如果a是最小值(a = 1),b = sqrt(c * c - 1)。
因此b必须介于该值和c -1之间。
此外,由于b必须是整数,因此需要找到第一个为整数的值。
Now, a property of squares:
The squares are: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, ...
The differences: -, 3, 5, 07, 09, 11, 13, 15, 17, 019, 021, ...
That means a square can be written as a summation of ODD numbers:
1 + 3 + 5 + 7 + n+...
where n = number the summation is a square of.
因此,正好有小于c * c的c平方数,您可以使用简单的减法来识别它们。
回到开头,取b = sqrt(c c - 1),向下舍入并取b b,得到方b必须在上面,并且 a = 1 。找到c c - (a a + b b)。这应该为您提供必须添加的数字才能达到c * c。
由于您可以将3 + 5 + 7 + ...
添加到a,b+2 + b+4 + b+6 + ...
添加到b,您只需根据总和而不是广场本身找到正确的字词:)