目录
基本性质
勾股数组我们都很熟悉,给一个勾股数组同乘一个整数得到的仍是勾股数组,但我们对它并不感兴趣,今天我们只研究它的本原形式(当然是在正整数范围内)。
本原勾股数组(PPT)是一个满足 $ a^{2}+b^{2}=c^{2} $ 的三元组 $ (a,b,c) $ ,且 \(a,b,c\) 互素(除1外没有其他公因数)。
例如:$ (3,4,5) (5,12,13) (15,8,17) (7,24,25) (21,20,29) (35,12,37) (9,40,41) $
观察这些例子,我们容易得到一些结论。例如,
性质1.(1) 本原勾股数组 $ (a,b,c) $ 中, \(a\)与\(b\)奇偶性不同,并且\(c\)为奇数。
这是正确的,证明如下(分类讨论):
若 \(a,b\) 均为偶数,那么\(c\)也为偶数,则此勾股数组不是本原的,排除;
若 \(a,b\) 均为奇数,那么\(c\)为偶数,则必存在正整数 \(x,y,z\) 使得 $ a=2x+1, b=2y+1, c=2z$ ,于是有
由于两边奇偶性不同,故等式不成立;
因此\(a,b\)奇偶性不同,由此\(c\)为奇数(方便起见,我们约定,如无特殊说明,下文中\(a\)为奇数,\(b\)为偶数)
勾股数组定理
有了这个性质以后,我们就可以开始考虑求解一个问题:如何求出所有的本原勾股数组?换句话说,如何表示出方程\(a^{2}+b^{2}=c^{2}\)(\(a\)为奇数,\(b\)为偶数,且\(a,b,c\)互素)的所有正整数解?
先写出结论:
(勾股数组定理)每个本原勾股数组(a,b,c)(a为奇数,b为偶数)均可以由下面的公式给出
下面,我们将使用因式分解与整除性证明这一定理。
首先移项并进行因式分解:\(a^{2}=(c+b)(c-b)\)
然后……就没有思路了 o(╯□╰)o 别急,我们先列个表看看这个式子有什么性质:
我们发现,貌似..... \(c+b\) 与 \(c-b\) 都是完全平方数诶,而且 \(c+b\) 与 \(c-b\) 好像是互素的。等等, \(c+b\) 与 \(c-b\) 的积\(a^{2}\)是完全平方数,假设 \(c+b\) 与 \(c-b\) 互素,那么由唯一分解定理,就可以推出 \(c+b\) 与 \(c-b\) 都是完全平方数(这是显然的,因为 \(c+b\) 与 \(c-b\) 分解到的素数完全不同)。于是接下来证明 \(c+b\) 与 \(c-b\) 互素:设整数d整除 \(c+b\) 与 \(c-b\) (即\(d\)为 \(c+b\) 与 \(c-b\) 的公因数),那么\(d\)也整除
又 \(b\) 与 \(c\) 互素,那么\(d\)只能等于1或2。又\(d\)整除\(c-b\)(奇数),那么\(d\)只能等于1(或者也可以由\(d\)整除 \((c-b)(c+b)=a^{2}\) 且\(a\)为奇数推出)。于是 \(c+b\) 与 \(c-b\) 的公因数只有1(也即互素),即可得到 \(c+b\) 与 \(c-b\) 均为完全平方数,于是有:
其中\(s>t≥1\),\(s,t\)互素且均为奇数(这样才能满足 \(c+b\) 与 \(c-b\) 的其它性质)
关于\(c\)与\(b\)解方程,并代入求\(a\)得到
代码与例题
那么,这个定理有什么用呢?当然就是打表列举本原勾股数组了,代码如下:
int gcd(int a,int b){ //求a,b的最大公因数
return b==0?a:gcd(b,a%b);
}
void ppt_table(int n){ //打印所有c不超过n的本原勾股数组
int a,b,c;
int maxs=(int)sqrt(2*n); //s的上界
for(int s=2;s<=maxs;s++)
for(int t=1;t<s;t++)
if(s%2 && t%2 && gcd(s,t)==1){
a=s*t;
b=(s*s-t*t)/2;
c=(s*s+t*t)/2;
if(c<=n) printf("%d %d %d",a,b,c);
}
}
例题(这个知识点的题几乎没有,事实上我只找到这一个):
洛谷 UVA106 费马vs毕达哥拉斯
题意:给定\(N\),求:1.满足\(c≤N\)的本原勾股数组的个数;2.满足\(c≤N\)的勾股数组(不一定本原)都不包含的正整数 \(p(0<p≤N)\) 的个数。
分析:使用勾股数组定理,将上面的代码稍稍更改一下即可。
展开查看源代码
``` #includeconst int N=1e6+5;
int vis[N],cnt,ans;
int gcd(int a,int b){
return b0?a:gcd(b,a%b);
}
void solve(int n){
int a,b,c;
int maxs=(int)sqrt(2*n);
for(int s=2;s<=maxs;s++)
for(int t=1;t<s;t++)
if(s%2 && t%2 && gcd(s,t)1){
a=st;
b=(ss-tt)/2;
c=(ss+tt)/2;
if(c<=n) cnt++;
for(int k=1;kc<=n;k++)
vis[ka]=vis[kb]=vis[k*c]=1;
}
}
int main(){
int n;
while(scanf("%d",&n)==1){
solve(n);
for(int i=1;i<=n;i++)
if(!vis[i]) ans++;
printf("%d %d\n",cnt,ans);
memset(vis,0,sizeof(vis));
cnt=ans=0;
}
return 0;
}
</details>
_____
## <span id="4">其他性质</span>
有没有注意到第一个性质的序号是“1.(1)”?没错,这样类似的性质还有两条,证明方法是类似的:
>**性质1.(2) 本原勾股数组 $ (a,b,c) $ 中, $a$ 与 $b$ 有且仅有一个是$3$的倍数,并且$c$不是$3$的倍数。**
>**性质1.(3) 本原勾股数组 $ (a,b,c) $ 中, $a,b,c$ 中有且仅有一个是$5$的倍数。**
证明方法与性质1.(1)完全类似,分类讨论并一一排除即可。值得一提的是,在证明 $a,b,c$ 不可能都不是$5$的倍数时,会发现诸多情况中,左式模$5$的值总是$0,2,3$,而右式的总是$1,4$,于是这一情况不成立。
另外,由勾股数组定理也可以推出几条~~有趣的~~性质:
>**性质2. 本原勾股数组 $ (a,b,c) $ 中, 若 $s-t=2$,则 $c-a=2$。**
>**性质3. 本原勾股数组 $ (a,b,c) $ 中, $2(c-a)$ 是完全平方数。**
证明:由勾股数组定理,$2(c-a)=s^{2}+t^{2}-2st=(s-t)^{2}=4$,故 $s-t=2$.
______
## <span id="5">与单位圆的联系</span>
用 $c^{2}$ 除方程 $ a^{2}+b^{2}=c^{2} $ 得到
<center>$ (\frac{a}{c})^{2}+(\frac{b}{c})^{2}=1$</center>
因此,有理数对 $(a/c,b/c)$ 是方程 $x^{2}+y^{2}=1$ 的解。
令 $u=\frac{s+t}{2},v=\frac{s-t}{2}$ ,
由勾股数组定理得到, $(a,b,c)=(u^{2}-v^{2},2uv,u^{2}+v^{2})$
同除以 $u^{2}+v^{2}$ ,得到 $(\frac{u^{2}-v^{2}}{u^{2}+v^{2}},\frac{2uv}{u^{2}+v^{2}},1)$
令 $m=u/v$,于是有 $(a,b)=(\frac{1-m^{2}}{1+m^{2}},\frac{2m}{1+m^{2}})$ ,这便是可以给出单位圆上所有有理点的定理:
>**定理:圆 $x^{2}+y^{2}=1$ 上的所有坐标为有理数的点都可以由公式**
>**<center> $(x,y)=(\frac{1-m^{2}}{1+m^{2}},\frac{2m}{1+m^{2}})$ </center>**
>**得到,其中$m$取有理数值。(点 $(-1,0)$ 除外,这是当 $m\to\infty$ 的极限值)**
事实上,上述推理并不严谨,这个定理严格一些的证明需要从过点 $(-1,0)$ 的直线及其斜率出发,各位看官若是有兴趣可自行完成证明。
End.