我正在尝试编写一个程序,该程序打印给定范围N的毕达哥拉斯三元组(a ^ 2 + b ^ 2 = c ^ 2),其中a< = b< = c< = N。
#include <stdio.h>
int main()
{
int a = 0, b = 0, c = 0, N, T,c2;
scanf("%d", &T);
while(T--)
{
int counter = 0;
scanf("%d", &N);
{
for (c = 0; c <=N; c++)
{
for (b = 0; b < c; b++)
{
for (a = 0; a < b; a++)
{
c2 = c*c;
if (a*a + b*b == c2 )
//if(sqrt (pow(a,2) + pow(b,2)) == c)
{
++counter;
printf("\n %d , %d, %d \n",a,b,c); }
}
}
}
}
printf("%d\n", counter);
}
return 0;
}
这适用于N <1000。对于更高的N,比如10000,这需要花费很多时间。 有没有更好的方法来优化这个编程或任何更好的算法而不是暴力,这样,计算更高的N需要更少的时间?
答案 0 :(得分:1)
根据数论,毕达哥拉斯三元组由(2pq,p ^ 2-q ^ 2,p ^ 2 + q ^ 2)参数化。你可以枚举这些,只要c> 1,就可以中止N.这当然是最佳的,因为你进行了与三元组一样多的计算......
答案 1 :(得分:0)
首先,只要c2
的新值可用,您就可以计算c
:
for (c = 0; c <=N; c++)
{
/* compute c2 here */
这可以节省为每个b
和a
反复计算的时间。
b
也是如此:只要b
可用,就可以计算b
的平方,而不是a
的每个值。您的编译器可能会自动应用这些优化,但不一定。
最后,a
只有一个值可以使等式成为真,此值为sqrt(c2 - b2)
。对于较大的b
值,计算此表达式并检查是否使方程式为真,而不是测试0
和b
之间的所有值,要快得多。如果对sqrt(c2 - b2)
使用双精度计算,那么在N
约为2 26 之前,浮点近似不会成为问题。
答案 2 :(得分:0)
您可以通过以下计算减少一个变量。如果我们假设
a = m^2 - n^2, b = 2mn, c = m^2 + n^2
让我们检查它是否满足a^2 + b^2 = c^2
:
a^2+b^2 = (m^2 - n^2)^2 + (2mn)^2 = (m^2 + n^2)^2 = c^2.
现在,我们可以遍历所有可能的m
和n
并生成相应的a
,b
,c
。
这是我用过的最快的方法。但是,我不知道是否存在任何O(1)
或O(log(n))
数学解决方案。