题目描述
传送门
题目大意:求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
题解
x2+y2=r2
x2=r2−y2
x=(r+y)(r−y)−−−−−−−−−−−√
设
d=gcd(r+y,r−y),A=r+yd,B=r−yd
式子变形为
x2=d2∗A∗B
因为x,d都是完全平方数,所以
A∗B
也是完全平方数,
A!=B
所以
A,B
分别是完全平方数。
那么设
A=a∗a,B=b∗b
a2=r+yd,b2=r−yd
a2+b2=2rd
那么枚举2r的因数d,再枚举a,判断是否有满足条件的(a,b),更新答案即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
LL r,ans;
LL gcd(LL x,LL y)
{
if (!x||!y) return 0;
LL r;
while (y){
r=x%y;
x=y; y=r;
}
return x;
}
bool check(LL x,LL y)
{
if (x!=y&&gcd(x,y)==1) return true;
return false;
}
void solve(LL x)
{
LL t=2*r/x;
for (LL i=1;i<=sqrt(t/2.0);i++) {
LL a=floor((double)sqrt((t-i*i)*1.0));
if ((a*a+i*i)!=t) continue;
if(check(a,i)) ans++;
}
}
int main()
{
freopen("a.in","r",stdin);
scanf("%lld",&r);
for (LL d=1;d*d<=2*r;d++)
if ((2*r)%d==0) {
solve(d);
if (d*d!=r*2) solve(2*r/d);
}
printf("%lld\n",ans*4+4);
}