POJ 1305:Fermat vs. Pythagoras - 勾股定理/毕达哥拉斯三元组

题意:
题意:给一个数n,求满足x^2+y^2=z^2,x<y<z<=n,并且x,y,z互素。
思路:
根据毕达哥拉斯三元组相关定理(《数论及应用》P110的定理4.5),几个未知数满足方程组,要求所给范围内的本原毕达哥拉斯三元组数,只需对m,n分别枚举。然后将三元组乘i,即可。

我们知道这个勾股方程可以化为(r^2-s^2)^2+(2*r*s)^2=(r^2+s^2)^2,x=r^2-s^2,y=2*r*s,z=r^2+s^2,所以可以枚举。r,s只能有一个是奇数。

好好消化啊

//

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1000001;
bool flag[N];

int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}

void solve(int t){
int tmp,m,n,i,ans1,ans2,x,y,z;
ans1=ans2=0;
memset(flag,0,sizeof(flag));
tmp=(int)sqrt(t+0.0);
for(n=1;n<=tmp;n++){
for(m=n+1;m<=tmp;m++){
if(m*m+n*n>t) break;
if(n%2!=m%2){
if(gcd(m,n)==1){
x=m*m-n*n;
y=2*m*n;
z=m*m+n*n;
ans1++;
for(i=1;;i++){
if(i*z>t) break;
flag[i*x]=1;
flag[i*y]=1;
flag[i*z]=1;
}
}
}
}
}
for(i=1;i<=t;i++)
if(!flag[i]) ans2++;
printf("%d %d\n",ans1,ans2);
}

int main(){
int n;
while(~scanf("%d",&n))
solve(n);
return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值