#include <stdio.h>
int main()
{
int i,j,k,t;
long int n;
int count;
int a,b;
float c;
scanf("%d",&t);
for(k=0;k<t;k++)
{
count=0;
scanf("%d",&n);
for(i=1;i<n;i++)
{
a=pow(i,2);
for(j=i;j<n;j++)
{
b=pow(j,2);
c=sqrt(a+b);
if((c-floor(c)==0)&&c<=n)
++count;
}
}
printf("%d\n",count);
}
return 0;
}
以上是一个c代码,用于计算范围1..n
范围内毕达哥拉斯三元组的数量。
我该如何优化它?它耗费大量输入。
1·; = T&LT; = 100
1·; = N&LT = 10 ^ 6
答案 0 :(得分:1)
你的内部两个循环是O(n * n)所以没有太多可以在不改变算法的情况下完成。只是看看内循环,我能在短时间内得出的最好结果如下:
unsigned long long int i,j,k,t;
unsigned long long int n = 30000; //Example for testing
unsigned long long int count = 0;
unsigned long long int a, b;
unsigned long long int c;
unsigned long long int n2 = n * n;
for(i=1; i<n; i++)
{
a = i*i;
for(j=i; j<n; j++)
{
b = j*j;
unsigned long long int sum = a + b;
if (sum > n2) break;
// Check for multiples of 2, 3, and 5
if ( (sum & 2) || ((sum & 7) == 5) || ((sum & 11) == 8) ) continue;
c = sqrt((double)sum);
if (c*c == sum) ++count;
}
}
一些评论:
unsigned int
以获得x2速度增加(或比原始速度快约x4)。i > 65535
时原始代码有整数溢出,这就是我为所有内容切换到64位整数的原因。答案 1 :(得分:0)
这实际上取决于您期望的基准。
但就目前而言,力量功能可能是瓶颈。我想你可以做以下两件事之一:
a)预先计算并保存在文件中,然后将所有平方值加载到字典中。根据输入大小,可能会加载内存。
b)记住先前计算的平方值,以便再次询问时,可以通过节省CPU时间在那里重复使用它。这再一次,最终会加载你的记忆。
答案 2 :(得分:0)
您可以将索引定义为(unsigned)long或甚至(unsigned)long long,但是您可能必须使用big num库来解决大量问题。使用未签名的uppers您的Max数量限制但强制您使用正数。我怀疑你是否需要更长的时间。 您的问题似乎是优化代码以使其更快。如果您阅读毕达哥拉斯三元组,您将看到有一种方法可以使用整数参数计算它们。如果3 4 5是三元组,那么我们知道2 * 3 2 * 4 2 * 5也是三元组,k * 3 k * 4 k * 5也是三元组。您的算法正在检查所有这些三元组。有更好的算法可供使用,但我担心你必须在Google上搜索关于毕达哥拉斯三胞胎的研究。