bzoj1041

参考链接:
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=2n):
(z+x)/2是整数,且(zx)/2是整数,
((z+x)/2,(zx)/2)|x((z+x)/2,(zx)/2)|z(只要把(z+x)/2(zx)/2相加减,就能得到这样的结论。)
又因为本原解中,(x.z)=1,所以((z+x)/2,(zx)/2)=1
又因为(z+x)/2>(zx)/2n2=((z+x)/2)((zx)/2),
所以(z+x)/2=r2(zx)/2=s2n=rs,
r>s>0,(r,s)=1,2(r+s)
z=r2+ss,x=r2s2,y=2rs
易证,只要满足这种形式就满足 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++){//rs等于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时,xy互换没什么影响,但是这里影响点的个数,所以要判断如果xy不相同的话,要多加一个。
                        ans++;
                        //printf("%d %d\n",temps,i);
                    }
                }
            }
        }
        ans=ans*4+4;

        printf("%d\n",ans);
        //break;//加不及break都能ac,这是为什么呢?
    }

    return 0;
}
posted @ 2015-10-06 20:33  buzhidaohahaha  阅读(86)  评论(0编辑  收藏