概念
本原勾股数组(PPT)是一个三元组(a,b,c),其中a,b,c没有公因数即gcd(a,b,c)=1
且满足
a
2
+
b
2
=
c
2
a^{2}+b^{2}=c^{2}
a2+b2=c2
(3,4,5), (5,12,13), (8,15,17), (7,24,25), (20,21,29), (9,40,41)等
性质
(1) a与b奇偶性不同且c总为奇数
证明:我们用分情况讨论的方式来证明
- 若a,b都为偶数,那么c也为偶数,则a,b,c有公因子2,不符合本原的定义
- 若a,b都为奇数,那么c必为偶数
设有a=2x+1,b=2y+1,c=2z
得 ( 2 x + 1 ) 2 + ( 2 y + 1 ) 2 = 4 z 2 (2x+1)^{2}+(2y+1)^{2}=4z^{2} (2x+1)2+(2y+1)2=4z2
$ \Rightarrow 4x{2}+4x+4y{2}+4y+2=4z^{2}$
⇒ 2 x 2 + 2 x + 2 y 2 + 2 y + 1 = 2 z 2 \Rightarrow 2x^{2}+2x+2y^{2}+2y+1=2z^{2} ⇒2x2+2x+2y2+2y+1=2z2
等式左边为一个奇数而等式右边为一个偶数,这是不可能的
所以以上得a,b的奇偶性不同,且c为奇数
(2)
a
2
=
c
2
−
b
2
=
(
c
−
b
)
(
c
+
b
)
a^{2}=c^{2}-b^{2}=(c-b)(c+b)
a2=c2−b2=(c−b)(c+b)
代入几个本原勾股数组
3
2
=
5
2
−
4
2
=
(
5
−
4
)
(
5
+
4
)
=
1
⋅
9
3^{2}=5^{2}-4^{2}=(5-4)(5+4)=1\cdot9
32=52−42=(5−4)(5+4)=1⋅9
1
5
2
=
1
7
2
−
8
2
=
(
17
−
8
)
(
17
+
8
)
=
9
⋅
25
15^{2}=17^{2}-8^{2}=(17-8)(17+8)=9\cdot25
152=172−82=(17−8)(17+8)=9⋅25
3
5
2
=
3
7
2
−
1
2
2
=
(
35
−
12
)
(
35
+
12
)
=
25
⋅
49
35^{2}=37^{2}-12^{2}=(35-12)(35+12)=25\cdot49
352=372−122=(35−12)(35+12)=25⋅49
(c-b)和(c+b)都是平方数
证明一下
设d为(c-b)和(c+b)的公因数即(c-b)=xd (c+b)=yd
那么(c-b)+(c+b)=2c=d(x+y)
(c+b)-(c-b)=2b=d(y-x)
即2c与2b都有d这个因子,但c和b互质,所以d=1或2,而
a
2
=
(
c
−
b
)
(
c
+
b
)
=
x
y
d
2
a^{2}=(c-b)(c+b)=xyd^{2}
a2=(c−b)(c+b)=xyd2且a为奇数,所以d为偶数,所以d=1
故得(c-b)和(c+b)互质,互质的两个数相乘为平方数只有这两个数为平方数时成立
记为
c
+
b
=
s
2
c+b=s^{2}
c+b=s2
c
−
b
=
t
2
c-b=t^{2}
c−b=t2
其中
s
>
t
≥
1
s>t\geq 1
s>t≥1,且s和t是没有公因数的奇数
c
=
s
2
+
t
2
2
c=\frac{s^{2}+t^{2}}{2}
c=2s2+t2
b
=
s
2
−
t
2
2
b=\frac{s^{2}-t^{2}}{2}
b=2s2−t2
a
=
(
c
−
b
)
(
c
+
b
)
=
s
t
a=\sqrt{(c-b)(c+b)}=st
a=(c−b)(c+b)=st
- 故 a = s t a=st a=st b = s 2 − t 2 2 b=\frac{s^{2}-t^{2}}{2} b=2s2−t2 c = s 2 + t 2 2 c=\frac{s^{2}+t^{2}}{2} c=2s2+t2 ,其中 s > t ≥ 1 s>t\geq 1 s>t≥1,且s和t是没有公因数的奇数
例题POJ1305
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
using namespace std;
bool vis[1000005];
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int ans=0;
memset(vis,0,sizeof(vis));
for(int s=3;s<=n;s+=2)
for(int t=1;t<s;t+=2)
{
if(gcd(s,t)==1)
{
int a=s*t;
int b=(s*s-t*t)/2;
int c=(s*s+t*t)/2;
if(c<=n)
ans++;
for(int i=1;i*c<=n;i++)
{
vis[i*a]=1;
vis[i*b]=1;
vis[i*c]=1;
}
}
}
int ans1=0;
for(int i=1;i<=n;i++)
if(!vis[i])
ans1++;
printf("%d %d\n",ans,ans1);
}
return 0;
}