BZOJ 1041: [HAOI2008]圆上的整点

1041: [HAOI2008]圆上的整点

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3621  Solved: 1605
[Submit][Status][Discuss]

Description

  求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。

Input

  只有一个正整数n,n<=2000 000 000

Output

  整点个数

Sample Input

4

Sample Output

4

HINT

 

Source

 
[Submit][Status][Discuss]

 

一道几何数学好题。

 

根据圆的方程,$X^{2}+Y^{2}=R^{2}$

可以变形得到,$Y^{2}=R^{2}-X^{2}$

根据平方差公式,$Y^{2}=(R+X)*(R-X)$

左右取算数平方根,$Y= \sqrt{(R+X)*(R-X)}$

设$d=gcd(R+X,R-X)$,即$d$为$R+X$和$R-X$的最大公约数

设$A=\frac{R-X}{d}$,$B=\frac{R+X}{d}$,那么显然有$A$和$B$互质

那么$Y=d*\sqrt{A}*\sqrt{B}$,为了让$Y$为整数,显然需要$\sqrt{A}$和$\sqrt{B}$为整数

设$a=\sqrt{A}$,$b=\sqrt{B}$,有$a$和$b$不等且互质,$a \lt b$

$A+B=a^{2}+b^{2}=\frac{R+X}{d}+\frac{R-X}{d}=\frac{2R}{d}$

那么$d$需要是$2R$的约数,这个可以$\sqrt{2R}$的枚举

对于一个$d$,再枚举$a$,注意$2a^{2} \lt a^{2}+b^{2}=\frac{2R}{d}$

所以$a$只需要在$\sqrt{\frac{R}{d}}$的范围内枚举

 

注意最后加上坐标轴上的4个整点

 

 1 #include <bits/stdc++.h>
 2 
 3 typedef long long lnt;
 4 
 5 using namespace std;
 6 
 7 lnt gcd(lnt a, lnt b)
 8 {
 9     return b ? gcd(b, a % b) : a;
10 }
11 
12 signed main(void)
13 {
14     lnt R, ans = 0; scanf("%lld", &R);
15     
16     for (lnt d = 1; d*d <= (R << 1); ++d)
17         if ((R << 1) % d == 0)
18         {
19             for (lnt a = 1; a*a <= R/d; ++a)
20             {
21                 double b = sqrt((2*R) / d - a*a);
22                 lnt bb = floor(b);
23                 if (b != bb)
24                     continue;
25                 if (gcd(a, bb) != 1)
26                     continue;
27                 if (a != b)
28                     ++ans;
29             }
30             
31             if (d*d != 2*R)
32             for (lnt a = 1; a*a <= d/2; ++a)
33             {
34                 double b = sqrt(d - a*a);
35                 lnt bb = floor(b);
36                 if (b != bb)
37                     continue;
38                 if (gcd(a, bb) != 1)
39                     continue;
40                 if (a != b)
41                     ++ans;
42             }
43         }
44         
45     printf("%lld\n", ans*4 + 4);
46 }

 

@Author: YouSiki 

posted @ 2017-01-07 09:35  YouSiki  阅读(339)  评论(0编辑  收藏  举报