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

Finding number of Pythagorean triples within a given range

本文关键字:三元组 毕达哥拉斯 查找 范围内      更新时间:2023-10-16

我想写一个程序,打印毕达哥拉斯三元组(a^2 + b^2 =c ^2)对于给定范围N,其中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("%dn", counter);
  }
  return 0;
}

这对于N<1000很有效。对于更大的N,比如10000,这会花费很多时间。是否有更好的方法来优化这个程序或更好的算法,而不是暴力破解,以便花费更少的时间来计算更高的N ?

根据数论,毕达哥拉斯三元组的参数化为(2pq, p^2-q^2, p^2+q^2)。你可以枚举这些,只要c> n就终止,这当然是最优的,因为你要做的计算和三元组一样多。

首先,您可以在c的新值可用时立即计算c2:

 for (c = 0; c <=N; c++)
  {
   /* compute c2 here */

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

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

最后,a只有一个值能使等式成立,这个值就是sqrt(c2 - b2)。对于较大的b值,计算这个表达式并检查它是否使方程成立比测试0b之间的所有值要快得多。如果对sqrt(c2 - b2)使用双精度计算,那么在N约为226之前,浮点近似将不会成为问题。

您可以通过以下计算减少一个变量。如果我们假设

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,并生成相应的a, b, c

这是我用过的最快的方法。然而,我不知道是否存在O(1)O(log(n))的数学解。