参考链接:
http://www.cppblog.com/zxb/archive/2010/10/18/130330.html
http://blog.csdn.net/popoqqq/article/details/39895149
《初等数学》(潘承洞):
对于具有
x2+y2=z2
这种形式的式子来说,求它的本原解
(即 x>0,y>0,z>0,(x,y,z)=1,但是可以得出(x,y)=1,(y,z)=1,(x,z)=1)
时具有以下性质:x和y不可能同时为奇数。所以求解的答案必然是x,y一个偶数,一个奇数,z是一个奇数,那么我们只要求出y为偶数时所有的可行本原解,即为所有的本原解。
当y是偶数时(设 y=2∗n):
(z+x)/2是整数,且(z−x)/2是整数,
且((z+x)/2,(z−x)/2)|x,((z+x)/2,(z−x)/2)|z(只要把(z+x)/2和(z−x)/2相加减,就能得到这样的结论。)
又因为本原解中,(x.z)=1,所以((z+x)/2,(z−x)/2)=1。
又因为(z+x)/2>(z−x)/2,n2=((z+x)/2)∗((z−x)/2),
所以(z+x)/2=r2,(z−x)/2=s2,n=r∗s,
r>s>0,(r,s)=1,2不能整除(r+s)
z=r2+ss,x=r2−s2,y=2∗r∗s
易证,只要满足这种形式就满足 x2+y2=z2。
按照题解中的转化方式,就可以用o(sqrt(n))的方法解决了,比o(n)的方法少多了。
(这次尝试用了不同的博客编辑器,发现这个挺好看的,只不过找不到表情)
(Something for nothing. -《龙族》)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
#define N 100000
int fanum[N];
int facou;
void getfactor(int n){
facou=0;
for(int i=1;i*i<=n;i++){
if(n%i==0){
fanum[facou++]=i;
if(i*i!=n){//这个应该放在if(n%i==0)这个判断里面,而不是外面
fanum[facou++]=n/i;
}
}
}
return;
}
int gcd(int a,int b){
int c;
while(b){
c=b;
b=a%b;
a=c;
}
return a;
}
int main(){
int n;
int ans;
while(scanf("%d",&n)!=EOF){
getfactor(n);
//printf("%d\n",n);
/*for(int i=0;i<facou;i++){
printf("%d ",fanum[i]);
}
printf("\n");*/
ans=0;
for(int i=0;i<facou;i++){
int tempz=fanum[i];
for(int i=1;i*i<=tempz;i++){//r和s等于0的情况另算
int tempssq=tempz-i*i;
int temps=sqrt(tempssq);
if(temps>0&&i>temps&&temps*temps==tempssq&&gcd(temps,i)==1&&(i+temps)%2){
ans++;
//printf("%d %d %d\n",tempz,i,temps);
if(i*i-temps*temps!=2*i*temps){//在解方程x^2+y^2=z^2时,x和y互换没什么影响,但是这里影响点的个数,所以要判断如果x和y不相同的话,要多加一个。
ans++;
//printf("%d %d\n",temps,i);
}
}
}
}
ans=ans*4+4;
printf("%d\n",ans);
//break;//加不及break都能ac,这是为什么呢?
}
return 0;
}