Description
求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
Input
只有一个正整数n,n<=2000 000 000
Output
整点个数
Sample Input
4
Sample Output
4
解题思路:还是没有解题思路啊,之前就看过这道题,但是一直不知道怎么做,今天又碰到了,开心。考虑到这个题暴力枚举是O(n)的是肯定不行的,那怎么办呢?去翻题解发看到了题解真是ORZ,看来数论那一套我这个菜鸟是真学不会了。下面附一个题解链接。这里写链接内容
x^2+y^2=r^2
化简为 y^2=(r-x)(r+x)
我们令d=gcd(r-x,r+x)
则(r-x)/d与(r+x)/d一定互质,二者相乘为完全平方数,则二者一定都为完全平方数
令r-x=d*u^2,r+x=d*v^2
则有u,v互质,u
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL R, ans;
LL gcd(LL a, LL b)
{
return b == 0 ? a : gcd(b, a%b);
}
bool f(LL a, double b)
{
if(b == floor(b))
{
LL b1 = (LL)floor(b);
if(gcd(b1*b1, a*a) == 1 && b1*b1 != a*a) return true;
}
return false;
}
int main()
{
scanf("%lld", &R);
for(LL d = 1; d <= sqrt(2*R); d++)
{
if((2*R)%d == 0)
{
for(LL a = 1; a <= (LL)sqrt((2*R)/(2*d)); a++)
{
double b = sqrt(((2*R)/d) - a*a);
if(f(a, b)) ans++;
}
if(d != (2*R)/d)
{
for(LL a = 1; a <= (LL)sqrt(d/2); a++)
{
double b = sqrt(d - a*a);
if(f(a, b)) ans++;
}
}
}
}
ans = ans * 4 + 4;
printf("%lld\n", ans);
return 0;
}