勾股数:
- 凡是可以构成一个直角三角形三边的一组正整数,称之为勾股数。
- 勾股数 —— 构成直角三角形的充分且必要条件。
1.
首先来观察:3 4 5;5 12 13;7 24 25;9 40 41;11 60 61; ... ;发现这些勾股数都是以奇数开头,从3起就没有间断过。
于是:若是大于1的奇数,由于奇数平方还是奇数,它平方后就可以拆成相邻的两个整数相加,那么奇数与这两个整数构成一组勾股数。此规律对于任意大于1的奇数都成立。
证明:
设此奇数:,奇数=偶数+奇数
那么,
则:
证毕。
2.
再来观察: 4 3 5;6 8 10;8 15 17;10 24 26;… ;发现这些都是以偶数开头。
于是: 对于大于2的偶数,平方后除以4再减一或者加一即构成一组勾股数。也可以说:把这个偶数除以2再平方,然后这个平方数加一或者减一即得一组勾股数。
证明:
设此偶数:, 则另外两条边:
3.
任取两个正整数m、n(m>n),那么:
构成一组勾股数。
证明:将上面代数式带入验证即可。
以上可得:任意大于2的整数都可以找出另外两个数构成勾股数。
此外, 观察分析上述的勾股数,可看出它们具有下列二个特点:
- 直角三角形短直角边为奇数(大于1),另一条直角边与斜边是两个连续自然数。
- 如果短直角边为奇数,则直角三角形的周长等于短直角边的平方与其本身的和(由上述1可证明)。
- 下面来看一个典型例题:
Codeforces Round #368 (Div. 2)
题意很简单,由样例即可知:给出一个整数问是否能找出另外两个数使得构成一组勾股数。如不能则输出-1,反之,则输出任意符合的两个数。
很明显是上述1、2情况。
给出两种代码:
1.0 由自己摸索:
int main()
{
long long a;
while(~scanf("%I64d",&a))
{
if(a<3) printf("-1\n");//小于3不符合;
else
{
if(a%2) printf("%I64d %I64d\n",a*a/2,a*a/2+1);奇数很容易推导出来;
else
{
if((a/2)%2)
{
a/=2;
printf("%I64d %I64d\n",a*a/2*2,(a*a)/2*2+2);
continue;
}
if(a%3==0)
{
long long x=a/3;
printf("%I64d %I64d\n",4*x,5*x);
}
else if(a%4==0)
{
long long x=a/4;
printf("%I64d %I64d\n",3*x,5*x);
}
else if(a%5==0)
{
long long x=a/5;
printf("%I64d %I64d\n",3*x,4*x);
}
else printf("-1\n");
}
}
}
return 0;
}
2.0 用勾股数定理:
int main()
{
long long a;
while(~scanf("%I64d",&a))
{
if(a<3)
{
printf("-1\n");
continue;
}
if(a%2) printf("%I64d %I64d\n",a*a/2,a*a/2+1);
else
{
a/=2;
long long b=a*a-1;
long long c=b+2;
printf("%I64d %I64d\n",b,c);
}
}
return 0;
}//明显简短许多。