基于圆的对称性,我们只需要考虑第一象限的整点即可
满足条件的x,y都是整数
数学上这类问题我们通常用一个量表示另一个量
y^2=(r-x)(r+x) (r-x)(r+x)要是完全平方数
令d=gcd(r-x,r+x)
则y^2=d^2*a*b a=(r+x)/d b=(r-x)/d;
不难发现此时(a,b)=1 a≠b (不考虑坐标轴)
要想是完全平方数即a是完全平方数,b也是完全平方数
不难想到要先穷举d
通过a=(r+x)/d b=(r-x)/d;可整理得a+b=2r/d 也就是说d是2r的约数
穷举d的范围显然是1~sqrt(2r) O(sqrt(2r))
对于确定的d,我们再穷举a(1^2,2^2……) 这样我们就可以确定唯一的b(因为在第一象限)
然后在验证一下b是否是完全平方数,a,b是否互质即可
1 var d,dd,r,ans,a:int64; 2 i,m:longint; 3 b:double; 4 5 function gcd(a,b:int64):int64; 6 begin 7 if b=0 then exit(a) 8 else exit(gcd(b,a mod b)); 9 end; 10 11 function check(a,b:double):boolean; 12 var x,y:int64; 13 begin 14 if b=trunc(b) then 15 begin 16 x:=int64(trunc(a))*int64(trunc(a)); 17 y:=int64(trunc(b))*int64(trunc(b)); 18 if (gcd(x,y)=1) and (a<>b) then exit(true); 19 end; 20 exit(false); 21 end; 22 23 begin 24 readln(r); 25 m:=trunc(sqrt(2*r)); 26 for i:=1 to m do 27 begin 28 d:=int64(i); 29 if 2*r mod d=0 then 30 begin 31 a:=0; 32 while (a<trunc(sqrt(r/d))) do 33 begin 34 inc(a); 35 b:=sqrt((2*r/d)-a*a); 36 if check(a,b) then inc(ans); 37 end; 38 dd:=2*r div d; 39 if dd<>d then 40 begin 41 a:=0; 42 while (a<trunc(sqrt(r/dd))) do 43 begin 44 inc(a); 45 b:=sqrt(2*r/dd-a*a); 46 if check(a,b) then inc(ans); 47 end; 48 end; 49 end; 50 end; 51 writeln(ans*4+4); 52 end.