您的位置:首页 > 其它

bzoj1041

2015-10-06 20:33 399 查看
参考链接:

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=4∗p+1或者z=4∗p+3,把x化成类似的形式,在进行加减即可证明)

z=r2+ss,x=r2−s2,y=2∗r∗s

易证,只要满足这种形式就满足 x2+y2=z2。

按照题解中的转化方式,就可以用o(sqrt(n))的方法解决了,比o(n)的方法少多了。

(这次尝试用了不同的博客编辑器,发现这个挺好看的,只不过找不到表情)

(Something for nothing. -《龙族》)

2015.10.29:

宿舍连个暖宝宝的都不了电是个什么样的节奏?充会电,断会电,再充会,再断会,幸亏是大早晨,舍友都还在睡,不用电,否则他们不得揍死我吗?

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
#define N 100000

int fanum
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: