给你一个二维整数数组 circles ,其中 circles[i] = [xi, yi, ri] 表示网格上圆心为 (xi, yi) 且半径为 ri 的第 i 个圆,返回出现在 至少一个 圆内的 格点数目 。
注意:
- 格点 是指整数坐标对应的点。
- 圆周上的点 也被视为出现在圆内的点。
示例 1:
输入: circles = [[2,2,1]]
输出: 5
解释:
给定的圆如上图所示。
出现在圆内的格点为 (1, 2)、(2, 1)、(2, 2)、(2, 3) 和 (3, 2),在图中用绿色标识。
像 (1, 1) 和 (1, 3) 这样用红色标识的点,并未出现在圆内。
因此,出现在至少一个圆内的格点数目是 5 。
示例 2:
输入: circles = [[2,2,2],[3,4,1]]
输出: 16
解释:
给定的圆如上图所示。
共有 16 个格点出现在至少一个圆内。
其中部分点的坐标是 (0, 2)、(2, 0)、(2, 4)、(3, 2) 和 (4, 4) 。
提示:
1 <= circles.length <= 200circles[i].length == 31 <= xi, yi <= 1001 <= ri <= min(xi, yi)
解析: 本次周赛题目,主要要看的不是题目内容,而是提示部分,这道题的提示就很值得关注,最多只有200个圆,圆心最大在100, 100,半径最大也就100,说明空间很小,基本上暴力算也是ok的,可能仅需要一点点优化,不用考虑太复杂。 我的思路就是计算每个圆的外接矩形内所有的点是否在园内,优化的方法是利用对称性,只看一个圆的左下部分包含哪些点,横轴和纵轴直接补齐。
from math import sqrt
from typing import List
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Solution:
def in_circle(self, point_A: Point, point_B: Point, radius: int):
if (point_A.x - point_B.x) ** 2 + (point_A.y - point_B.y) ** 2 > radius ** 2:
return False
else:
return True
def countLatticePoints(self, circles: List[List[int]]) -> int:
point_set = set()
for circle in circles:
point_circle = Point(circle[0], circle[1])
radius = circle[2]
for x in range(point_circle.x - radius, point_circle.x):
for y in range(point_circle.y - radius, point_circle.y):
p = Point(x, y)
if self.in_circle(point_circle, p, radius):
point_set.add("%s|%s" % (x, y))
point_set.add("%s|%s" % (x, 2 * point_circle.y - y))
point_set.add("%s|%s" % (2*point_circle.x - x, y))
point_set.add("%s|%s" % (2*point_circle.x - x, 2 * point_circle.y - y))
for x in range(point_circle.x - radius, point_circle.x+radius + 1):
point_set.add("%s|%s" % (x, point_circle.y))
for y in range(point_circle.y - radius, point_circle.y+radius + 1):
point_set.add("%s|%s" % (point_circle.x, y))
return len(point_set)