1041: [HAOI2008]圆上的整点
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 4547 Solved: 2042
[Submit][Status][Discuss]
Description
求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
Input
只有一个正整数n,n<=2000 000 000
Output
整点个数
Sample Input
4
Sample Output
4
HINT
题解
x*x+y*y=r*r
y=sqrt((r-x)*(r+x))
设i=gcd(r-x,r+x),设A=(r-x)/i,B=(r+x)/i,显然gcd(A,B)=1。
那么y*y=i*i*A*B,因为A!=B,所以A和B一定都是平方数,设a=sqrt(A),b=sqrt(B),那么a*a+b*b=2*r/i。
那么枚举i,再枚举a,计算出b,再判断gcd(A,B)是否为1。
求出第一象限的点数都,ans=ans*4+4,因为坐标轴上有4个点。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define LL long long
using namespace std;
LL r,ans;
LL gcd(LL x,LL y){
if(!y)return x;
return gcd(y,x%y);
}
bool check(LL x,LL y){
if(gcd(x*x,y*y)==1&&x!=y)return true;
return false;
}
int main(){
scanf("%lld",&r);
double k;
for(LL i=1;i<=sqrt(2*r);i++){
if((2*r)%i==0){
for(LL j=1;j<=sqrt(r/i);j++){
k=sqrt(2*r/i-j*j);
if(k==floor(k))if(check(j,floor(k)))ans++;
}
if(2*r/i!=i){
for(LL j=1;j<=sqrt(i/2);j++){
k=sqrt(i-j*j);
if(k==floor(k))if(check(j,floor(k)))ans++;
}
}
}
}
printf("%lld\n",ans*4+4);
return 0;
}