以下的方法可用来找出勾股数。设 m > n 、 m 和 n 均是正整数,
若 m 和 n 是互质,而且 m 和 n 其中有一个是偶数,计算出来的 (a, b, c) 就是素勾股数。(若 m 和 n 都是奇数, (a, b, c) 就会全是偶数,不符合互质。)
所有素勾股数可用上述列式当中找出,这亦可推论到数学上存在无穷多的素勾股数。
例子[编辑]
小于 100 的素勾股数列表:
a | b | c |
---|---|---|
3 | 4 | 5 |
5 | 12 | 13 |
7 | 24 | 25 |
8 | 15 | 17 |
9 | 40 | 41 |
11 | 60 | 61 |
12 | 35 | 37 |
13 | 84 | 85 |
16 | 63 | 65 |
20 | 21 | 29 |
28 | 45 | 53 |
33 | 56 | 65 |
36 | 77 | 85 |
39 | 80 | 89 |
48 | 55 | 73 |
65 | 72 | 97 |
让我们把上述列式重组至以下列式:
有些勾股数组可以有同一个最小的勾股数。第一个例子是 20 ,它在以下两组勾股数之中出现:(20, 21, 29) 与 (20, 99, 101)。
其中最先例子是5,它在以下两组勾股数之中出现(3,4,5)及(5,12,13)。
在 15,386 组素勾股数的 1229779565176982820 ,它的最小与最大的勾股数组是:
与
试考虑它的质因数分解
它质因数的个数涉及不少素勾股数。当然,数学上存在比它大的素勾股数。
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e9+7;
ll n,used[1000000+10];
ll gcd(int x,int y)
{
if(x%y==0)
{
return y;
}
else
{
return gcd(y,x%y);
}
}
main()
{
while(~scanf("%d",&n))
{
ll a,b,c;
ll cnt = 0,cntused = 0;
memset(used,0,sizeof(used));
for(int i=1; i<=sqrt(n+0.5); i++)
{
for(int j=i+1; j*i<=n; j+=2)
{
if(gcd(i,j)==1)
{
a=j*j-i*i;
b=2*i*j;
c=i*i+j*j;
if(c<=n)
{
cnt++;
if(!used[a])
{
used[a]=1;
cntused++;
}
if(!used[b])
{
used[b]=1;
cntused++;
}
if(!used[c])
{
used[c]=1;
cntused++;
}
}
for(int k=2; k*c<=n; k++)
{
if(!used[k*a])
{
used[k*a]=1;
cntused++;
}
if(!used[k*b])
{
used[k*b]=1;
cntused++;
}
if(!used[k*c])
{
used[k*c]=1;
cntused++;
}
}
}
}
}
// cout<<cntused<<endl;
cout<<cnt<<" "<<n-cntused<<endl;
}
}