1041: [HAOI2008]圆上的整点
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4626 Solved: 2083
[Submit][Status][Discuss]
Description
求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
Input
只有一个正整数n,n<=2000 000 000
Output
整点个数
Sample Input
4
Sample Output
4
HINT
Source
这里先只考虑x,y都大于0的情况
如果x^2+y^2=r^2,则(r-x)(r+x)=y*y
令d=gcd(r-x,r+x),r-x=d*u^2,r+x=d*v^2,显然有gcd(u,v)=1且u<v
有2r=d*(u^2+v^2),y=d*u*v,x=d(v^2-u^2)/2
枚举2r的约数d,再花费sqrt(2r/d)的时间枚举u,求出v=sqrt(2r/d-u^2)然后判断gcd(u,v)=1
最后结果乘以4(四个象限)+4(坐标轴上)即可
如果x^2+y^2=r^2,则(r-x)(r+x)=y*y
令d=gcd(r-x,r+x),r-x=d*u^2,r+x=d*v^2,显然有gcd(u,v)=1且u<v
有2r=d*(u^2+v^2),y=d*u*v,x=d(v^2-u^2)/2
枚举2r的约数d,再花费sqrt(2r/d)的时间枚举u,求出v=sqrt(2r/d-u^2)然后判断gcd(u,v)=1
最后结果乘以4(四个象限)+4(坐标轴上)即可
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 ll ans,r,rr,d; 5 inline ll gcd(ll xx,ll yy){ 6 while(yy) {ll t=xx;xx=yy;yy=t%yy;} 7 return xx; 8 } 9 inline void solve(ll xx){ 10 for(ll i=1;i<=sqrt(1.0*xx);i++){ 11 ll t=int(sqrt(1.0*(xx-i*i)+0.5)); 12 if(i>=t) break; 13 if(1ll*t*t+1ll*i*i==1ll*xx&&gcd(i,t)==1) ans++; 14 } 15 } 16 int main(){ 17 //freopen("All.in","r",stdin); 18 //freopen("a.out","w",stdout); 19 cin>>r; 20 rr=r<<1; 21 ans=1; 22 for(ll i=1;i<=sqrt(1.0*rr);i++){ 23 if(rr%i!=0) continue; 24 solve(rr/i); 25 if(i*i==rr) break; 26 solve(i); 27 } 28 cout<<ans*4<<endl; 29 return 0; 30 }