数论-毕达哥拉斯三元组

方程形式: X^2 + Y^2 = Z^2 

X,Y,Z即勾股定理的三条直角边。

本元毕达哥拉斯的解即三边互质的一组解,如(3,4,5),其求法如下:

假定m,n为任意正整数 (m>n) ,

满足 gcd(m,n) = 1 且 m%2 != n%2

则:

X=m^2-n^2;

Y=2*m*n;

Z=m^2+n^2;

求得本元解后其解集即所有本元解的所有正整数倍数。

例题:POJ 1305  HDU 3939  FZU1669

POJ1305:

http://poj.org/problem?id=1305

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define maxn 1000005
struct node
{
    int x,y,z;
}ans[maxn];
bool vis[maxn];
int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
int main()
{
    int t;
    while(cin>>t)
    {
        memset(vis,0,sizeof(vis));
        int cnt=0;
        for(int i=1;i<=sqrt(t*1.0);i++)
        {
            for(int j=1;j<i;j++)
            {
                if(gcd(i,j)!=1 || i%2==j%2 ) continue;

                int dz=i*i+j*j;
                int dy=2*i*j;
                int dx=i*i-j*j;
                if(dz>t||dy>t) break;
                ans[cnt].x=dx;
                ans[cnt].y=dy;
                ans[cnt].z=dz;
                vis[ans[cnt].x]=1;
                vis[ans[cnt].y]=1;
                vis[ans[cnt].z]=1;
                cnt++;
            }
        }
        int sum=0;
        for(int i=0;i<cnt;i++)
        {
            int ma=ans[i].z;
            int tp=1;
            while(ans[i].z*tp<=t)
            {
                sum++;
                vis[tp*ans[i].x]=1;
                vis[tp*ans[i].y]=1;
                vis[tp*ans[i].z]=1;
                tp++;
            }
        }
        int ans2=0;
        for(int i=1;i<=t;i++)
        {
            if(vis[i]==0) ans2++;
        }
        cout<<cnt<<" "<<ans2<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/mochenmochen/p/5160223.html