解题思路
计算圆上整点的方法:
- 先处理坐标轴上的点
- 从最大可能的 坐标开始向下遍历
- 检查每个 对应的 是否为整数
关键点
- 先处理 为完全平方数的情况
- 从大到小遍历可能的 值
- 利用对称性计数
代码
#include <iostream>
#include <cmath>
using namespace std;
class Solution {
public:
int countPoints(int n) {
int count = 0;
// 处理坐标轴上的点
int r = (int)sqrt(n);
if (r * r == n) {
count += 4; // 如果r是整数,(±r,0)和(0,±r)是整点
--r;
}
// 遍历可能的y坐标
for (int y = r; y > 0; y--) {
int x = (int)sqrt(n - y * y);
if (x * x + y * y == n) {
count += 4; // 每找到一对(x,y),由对称性可得4个点
}
}
return count;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
while (cin >> n) {
Solution solution;
cout << solution.countPoints(n) << endl;
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
public int countPoints(int n) {
int count = 0;
// 处理坐标轴上的点
int r = (int)Math.sqrt(n);
if (r * r == n) {
count += 4;
--r;
}
// 遍历可能的y坐标
for (int y = r; y > 0; y--) {
int x = (int)Math.sqrt(n - y * y);
if (x * x + y * y == n) {
count += 4;
}
}
return count;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
Solution solution = new Solution();
System.out.println(solution.countPoints(n));
}
sc.close();
}
}
from math import sqrt
class Solution:
def count_points(self, n: int) -> int:
count = 0
# 处理坐标轴上的点
r = int(sqrt(n))
if r * r == n:
count += 4 # 坐标轴上的四个点
r -= 1
# 遍历可能的y坐标
for y in range(r, 0, -1):
x = int(sqrt(n - y * y))
if x * x + y * y == n:
count += 4 # 每组解可以得到四个对称点
return count
def main():
while True:
try:
n = int(input())
solution = Solution()
print(solution.count_points(n))
except EOFError:
break
if __name__ == "__main__":
main()
算法及复杂度
- 算法:枚举优化
- 时间复杂度:, 为半径平方
- 空间复杂度:,只需常数空间