在给定范围内找出毕达哥拉斯三元组的数量

时间:2014-06-10 12:25:56

标签: unix c++ c

我正在尝试编写一个程序,该程序打印给定范围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需要更少的时间?

3 个答案:

答案 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 */

这可以节省为每个ba反复计算的时间。

b也是如此:只要b可用,就可以计算b的平方,而不是a的每个值。您的编译器可能会自动应用这些优化,但不一定。

最后,a只有一个值可以使等式成为真,此值为sqrt(c2 - b2)。对于较大的b值,计算此表达式并检查是否使方程式为真,而不是测试0b之间的所有值,要快得多。如果对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.

现在,我们可以遍历所有可能的mn并生成相应的abc

这是我用过的最快的方法。但是,我不知道是否存在任何O(1)O(log(n))数学解决方案。