费马大定理和勾股数

大家都知道:若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;
}

猜你喜欢

转载自blog.csdn.net/qq_41157137/article/details/82153966