随笔 - 540  文章 - 0 评论 - 39 trackbacks - 0

基于圆的对称性,我们只需要考虑第一象限的整点即可
满足条件的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.
View Code

 

posted on 2014-10-16 22:31  acphile  阅读(84)  评论(0编辑  收藏