题目描述:
给你两个正整数 xCorner 和 yCorner 和一个二维整数数组 circles ,其中 circles[i] = [xi, yi, ri] 表示一个圆心在 (xi, yi) 半径为 ri 的圆。
坐标平面内有一个左下角在原点,右上角在 (xCorner, yCorner) 的矩形。你需要判断是否存在一条从左下角到右上角的路径满足:路径 完全 在矩形内部,不会 触碰或者经过 任何 圆的内部和边界,同时 只 在起点和终点接触到矩形。
如果存在这样的路径,请你返回 true ,否则返回 false。
代码思路:
这个代码是解决一个特定问题的算法,其目标是在给定的二维平面上,判断从左下角 (0, 0) 到右上角 (X, Y) 是否有一条路径,可以沿着给定的圆圈的边缘行走(直接或间接通过其他圆圈)到达。圆圈由它们的中心坐标和半径表示。这个问题可以通过并查集(Union-Find)数据结构以及几何计算来解决。以下是代码的详细思路:
这个算法的核心思想是利用并查集来高效地管理和查询元素之间的连通性,同时结合几何计算来判断圆与线段、圆与圆之间的相交关系。
代码实现:
class Solution:
def canReachCorner(self, X: int, Y: int, circles: List[List[int]]) -> bool:
n = len(circles)
fa = [-1] * (n+2)
def find(x):
if fa[x] == -1: return x
fa[x] = find(fa[x])
return fa[x]
def merge(x, y):
x, y = find(x), find(y)
if x != y:
fa[x] = y
def in_circle(x, y, r, x0, y0):
return (x0 - x) * (x0 - x) + (y0 - y) * (y0 - y) <= r * r
def cross_vertical(x, y, r, x0, y1, y2):
if y1 >= y:
return in_circle(x, y, r, x0, y1)
if y2 <= y:
return in_circle(x, y, r, x0, y2)
return abs(x0 - x) <= r
def cross_horizontal(x, y, r, x1, x2, y0):
if x1 >= x:
return in_circle(x, y, r, x1, y0)
if x2 <= x:
return in_circle(x, y, r, x2, y0)
return abs(y0 - y) <= r
for i1, c1 in enumerate(circles):
x1, y1, r1 = c1
# 和 (0,0), (0, Y) 相交
if cross_vertical(x1, y1, r1, 0, 0, Y): merge(i1, n)
# 和 (0, Y), (X, Y) 相交
if cross_horizontal(x1, y1, r1, 0, X, Y): merge(i1, n)
# 和 (0, 0), (X, 0) 相交
if cross_horizontal(x1, y1, r1, 0, X, 0): merge(i1, n+1)
# 和 (X, 0), (X, Y) 相交
if cross_vertical(x1, y1, r1, X, 0, Y): merge(i1, n+1)
for i2, c2 in enumerate(circles):
if i2 <= i1: continue
x2, y2, r2 = c2
if (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2):
xm = x1 * r2 + x2 * r1
ym = y1 * r2 + y2 * r1
s = r1 + r2
if xm >= 0 and ym >= 0 and xm <= X * s and ym <= Y * s:
merge(i1, i2)
return find(n) != find(n+1)