题目倒是很简洁明了……但是有点让人无从下手
我们一步一步来分析:
首先写出式子 X ^ 2 + Y ^ 2 = R ^ 2
移项 Y ^ 2 = R ^ 2 - X ^ 2
= (R + X)(R - X)
设 d = GCD(R + X, R - X)
则 Y ^ 2 = d ^ 2 * (R + X) / d * (R - X) / d
设 A = (R + X) / d, B = (R - X) / d
则 A != B 且 GCD(A, B) = 1
且 Y ^ 2 = d ^ 2 * A * B
由于Y ^ 2 是完全平方数, d ^ 2也是完全平方数, 而A, B互质,所以A, B都是完全平方数
设 A = a ^ 2, B = b ^ 2
则 a ^ 2 + b ^ 2 = 2 * R / d
说明 d 是 2 * R 的因数,以此可以在[1, sqrt(2 * R)]的范围内枚举i,当2 * R % i == 0时,i 和 2 * R / i都是2 * R 的因数。确定 2 * R / d 的值,假设a < b,我们再在[1, sqrt((2 * R / d) / 2)]的范围内枚举a, 算出对应的 A, b, B, 如果A, B都是完全平方数而且 A != B, GCD(A, B) == 1则方案数加1。这是一个象限的方案数,最后再* 4 再加上坐标轴上的4个即可
[Pay Attention]
用long long啊用long long!
注意以后求勾股数相关的都可以利用这里推出的结论……
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long sint;
sint n;
int ans;
sint gcd(sint a,sint b)
{
if(b==0) return a;
return gcd(b,a%b);
}
void check(sint lim)
{
sint A,B,a,b,b2;
sint tmp=sqrt(lim/2);
for(a=1;a<=tmp;a++)
{
B=lim-a*a;
b=sqrt(B);
if(B!=b*b) continue;
A=a*a;
if(A==B) continue;
if(gcd(A,B)!=1) continue;
ans++;
}
}
int main()
{
sint r,sqn;
cin>>r;
sqn = sqrt(r*2);
for(sint i = 1;i <= sqn;i++)
if( 2*r%i==0 )
{
check(i);
check(2*r / i);
}
printf("%d\n",(ans+1)*4);
return 0;
}