[BZOJ] 1041 圆上的整点【质因数分解】
题目
求一个给定的圆$(x^2+y^2=r^2)$,在圆周上有多少个点的坐标是整数。
题解
$x^2+y^2=r^2$
$y=\sqrt{(r+x)*(r-x)}$
$d=gcd((r+x),(r-x))$
$r+x=d*A,r-x=d*B$
$y=\sqrt{d*d*A*B}$
$A=a^2,B=b^2$
$r+x=d*a^2,r-x=d*b^2$
$d*(a^2+b^2)=2*r$
$a^2+b^2=r*2/d$
枚举d,枚举a,检验$gcd(a^2,b^2)$是否等于1,a是否不等于b
还有一个更为精妙的方法:https://www.bilibili.com/video/av12131743/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
LL r;
int ans=0;
inline bool ok(LL a,LL b)
{
if(__gcd(a*a,b*b)!=1 || a==b)
return false;
return true;
}
int main()
{
scanf("%lld",&r);
LL m=sqrt(2*r);
for(LL d=1;d<=m;d++)
if((2*r)%d==0)
{
LL mm=sqrt(d/2);
for(LL b=1;b<=mm;b++)
{
double tmp=sqrt(d-b*b);
LL a=(LL)tmp;
if(a<tmp) continue;
if(ok(a,b)) ans++;
}
if(d!=2*r/d)
{
mm=sqrt(r/d);
for(LL b=1;b<=mm;b++)
{
double tmp=sqrt(2*r/d-b*b);
LL a=(LL)tmp;
if(a<tmp) continue;
if(ok(a,b)) ans++;
}
}
}
printf("%d",ans*4+4);
return 0;
}
另一种方法:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int r,ans=1;
cin>>r;
int mm=sqrt(r);
for(int i=2;i<=mm;i++)
if(r%i==0)
{
int p=0;
while(r%i==0)
{
if(i%4!=3)
p+=2;
r/=i;
}
if(i!=2) ans*=(p+1);
}
if(r!=1 && r%4!=3)
ans*=3;
cout<<ans*4;
return 0;
}

浙公网安备 33010602011771号