方程形式: 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; }