前言:
大家都知道:若a^2 + b^2 = c^2,则(a,b,c)为一组勾股数,如(3,4,5);如果只给你一个数,你会怎么找到一组勾股数呢?
一.寻找勾股数:
若需要一組最小數為奇數的勾股數,可任意選取一個 3 或以上的奇數,將該數自乘為平方數,除以 2,答案加減 0.5 可得到 兩個新的數字,這兩個數字連同一開始選取的奇數,三者必定形成一組勾股數。但卻不一定是以這個選取數字為起首勾股 數的唯一可能,例如 (27, 364, 365) 並非是以 27 為起首的唯一勾股數,因為存在另一個勾股數是 (27, 36, 45),同樣也以 27 為首。 對於任何大於1的整數x,x 2+1、x 2 -1與2x,三個數必為畢氏數,例如:代入x為2,則x 2+1為5,x 2 -1為3,2x為4,(3,4,5) 為一組畢氏數。
對於任何大於1的整數x,x 2+1、x 2 -1與2x,三個數必為畢氏數,例如:代入x為2,則x 2+1為5,x 2 -1為3,2x為4,(3,4,5) 為一組畢氏數。
——《维基百科》
1)它的意思是:如果一组勾股数中最小的为奇数(设为a),令b=a*a/2.0-0.5,令c=a*a/2.0+0.5,则有(a,b,c)必为一组勾股数,即:a^2+b^2=c^2
2)对于大于1的任何整数x,(2x,x^2-1,x^2+1)也必为一组勾股数。
二.证明:
2)很好证明;
1)下面的证明来自《数论》(感谢作者)
这样得到的勾股数并不一定是最小的,例如 s = 27时,代入公式得(27,364,365),但同样存在(27,36,45)的勾股数组,利用计算机可以轻松解:a^2 = (c-b)*(c+b) ;必然存在 : 1=<(c-b)<=a , a =< (c+b) <= a^2,这里不能直接解不等式,因为还有前面等式的限制,这里是不是有点像高中的线性规划(1 =< x-y <= a;a =<x+y <= a^2;求(x-y)*(x+y)= a^2 的解);求最小的解法:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
int t,n,a,b,c;
while(cin>>t)
{
while(t--)
{
cin>>a;
int val=a*a;
for(int i=a-1;i>=1;i--) //i相当与(c-b)这个因子
{
if(val%i==0) //如果i = a^2的因子
{
int tep=val/i; //tep是a^2的另一个因子(c+b)
if((tep+i)%2==0) //相当于(c-b)+(c+b)= 2c,确保2c为偶数。
{
c=(tep+i)/2;
b=c-i;
break;
}
}
}
cout<<b<<" "<<c<<endl;
}
}
return 0;
}
这里你应该要想如果i从1开始循环呢?那么1是任何数的因子,另一个因子必为a^2,c =(a^2+1) / 2; b = c - 1 =(a^2-1) / 2;
同样就得到了上文的定理2.1的特殊情况。
三.费马大定理:
费马最后定理指出,若a^n+b^n=c^n ,而 n 是大于 2 的整数, (a, b, c) 即没有正整数解。
四.杭电经典题:
2018中国大学生程序设计竞赛 - 网络选拔赛:http://acm.hdu.edu.cn/showproblem.php?pid=6441
题意:
给你一个a、n,求出 b 和 c 使其满足 :a^n+b^n=c^n
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN=1e9;
int main()
{
int t,n,a;
while(cin>>t)
{
while(t--)
{
cin>>n>>a;
if(n==0||n>2) cout<<-1<<" "<<-1<<endl; //费马大定理
else if(n==1) cout<<1<<" "<<a+1<<endl;
else
{
ll b,c;
if(a%2) //a为奇数
{
b=a*a/2.0-0.5;
c=a*a/2.0+0.5;
}
else //a为偶数
{
int x=a/2;
b=x*x-1;
c=x*x+1;
}
cout<<b<<" "<<c<<endl;
}
}
}
return 0;
}