日渐头秃的代码日记 -- 第290场周赛第2题

159 阅读1分钟

给你一个二维整数数组 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 <= 200
  • circles[i].length == 3
  • 1 <= xi, yi <= 100
  • 1 <= 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)