[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; }