Skip to content

Commit 39584f5

Browse files
authored
feat: add solutions to lc problem: No.3235 (#3703)
No.3235.Check if the Rectangle Corner Is Reachable
1 parent fc4070e commit 39584f5

File tree

7 files changed

+863
-6
lines changed

7 files changed

+863
-6
lines changed

solution/3200-3299/3235.Check if the Rectangle Corner Is Reachable/README.md

+289-3
Original file line numberDiff line numberDiff line change
@@ -109,25 +109,311 @@ tags:
109109
#### Python3
110110

111111
```python
112-
112+
class Solution:
113+
def canReachCorner(
114+
self, xCorner: int, yCorner: int, circles: List[List[int]]
115+
) -> bool:
116+
def in_circle(x: int, y: int, cx: int, cy: int, r: int) -> int:
117+
return (x - cx) ** 2 + (y - cy) ** 2 <= r**2
118+
119+
def cross_left_top(cx: int, cy: int, r: int) -> bool:
120+
a = abs(cx) <= r and 0 <= cy <= yCorner
121+
b = abs(cy - yCorner) <= r and 0 <= cx <= xCorner
122+
return a or b
123+
124+
def cross_right_bottom(cx: int, cy: int, r: int) -> bool:
125+
a = abs(cx - xCorner) <= r and 0 <= cy <= yCorner
126+
b = abs(cy) <= r and 0 <= cx <= xCorner
127+
return a or b
128+
129+
def dfs(i: int) -> bool:
130+
x1, y1, r1 = circles[i]
131+
if cross_right_bottom(x1, y1, r1):
132+
return True
133+
vis[i] = True
134+
for j, (x2, y2, r2) in enumerate(circles):
135+
if vis[j] or not ((x1 - x2) ** 2 + (y1 - y2) ** 2 <= (r1 + r2) ** 2):
136+
continue
137+
if (
138+
(x1 * r2 + x2 * r1 < (r1 + r2) * xCorner)
139+
and (y1 * r2 + y2 * r1 < (r1 + r2) * yCorner)
140+
and dfs(j)
141+
):
142+
return True
143+
return False
144+
145+
vis = [False] * len(circles)
146+
for i, (x, y, r) in enumerate(circles):
147+
if in_circle(0, 0, x, y, r) or in_circle(xCorner, yCorner, x, y, r):
148+
return False
149+
if (not vis[i]) and cross_left_top(x, y, r) and dfs(i):
150+
return False
151+
return True
113152
```
114153

115154
#### Java
116155

117156
```java
118-
157+
class Solution {
158+
private int[][] circles;
159+
private int xCorner, yCorner;
160+
private boolean[] vis;
161+
162+
public boolean canReachCorner(int xCorner, int yCorner, int[][] circles) {
163+
int n = circles.length;
164+
this.circles = circles;
165+
this.xCorner = xCorner;
166+
this.yCorner = yCorner;
167+
vis = new boolean[n];
168+
for (int i = 0; i < n; ++i) {
169+
var c = circles[i];
170+
int x = c[0], y = c[1], r = c[2];
171+
if (inCircle(0, 0, x, y, r) || inCircle(xCorner, yCorner, x, y, r)) {
172+
return false;
173+
}
174+
if (!vis[i] && crossLeftTop(x, y, r) && dfs(i)) {
175+
return false;
176+
}
177+
}
178+
return true;
179+
}
180+
181+
private boolean inCircle(long x, long y, long cx, long cy, long r) {
182+
return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= r * r;
183+
}
184+
185+
private boolean crossLeftTop(long cx, long cy, long r) {
186+
boolean a = Math.abs(cx) <= r && (cy >= 0 && cy <= yCorner);
187+
boolean b = Math.abs(cy - yCorner) <= r && (cx >= 0 && cx <= xCorner);
188+
return a || b;
189+
}
190+
191+
private boolean crossRightBottom(long cx, long cy, long r) {
192+
boolean a = Math.abs(cx - xCorner) <= r && (cy >= 0 && cy <= yCorner);
193+
boolean b = Math.abs(cy) <= r && (cx >= 0 && cx <= xCorner);
194+
return a || b;
195+
}
196+
197+
private boolean dfs(int i) {
198+
var c = circles[i];
199+
long x1 = c[0], y1 = c[1], r1 = c[2];
200+
if (crossRightBottom(x1, y1, r1)) {
201+
return true;
202+
}
203+
vis[i] = true;
204+
for (int j = 0; j < circles.length; ++j) {
205+
var c2 = circles[j];
206+
long x2 = c2[0], y2 = c2[1], r2 = c2[2];
207+
if (vis[j]) {
208+
continue;
209+
}
210+
if ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) > (r1 + r2) * (r1 + r2)) {
211+
continue;
212+
}
213+
if (x1 * r2 + x2 * r1 < (r1 + r2) * xCorner && y1 * r2 + y2 * r1 < (r1 + r2) * yCorner
214+
&& dfs(j)) {
215+
return true;
216+
}
217+
}
218+
return false;
219+
}
220+
}
119221
```
120222

121223
#### C++
122224

123225
```cpp
124-
226+
class Solution {
227+
public:
228+
bool canReachCorner(int xCorner, int yCorner, vector<vector<int>>& circles) {
229+
using ll = long long;
230+
auto inCircle = [&](ll x, ll y, ll cx, ll cy, ll r) {
231+
return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= r * r;
232+
};
233+
auto crossLeftTop = [&](ll cx, ll cy, ll r) {
234+
bool a = abs(cx) <= r && (cy >= 0 && cy <= yCorner);
235+
bool b = abs(cy - yCorner) <= r && (cx >= 0 && cx <= xCorner);
236+
return a || b;
237+
};
238+
auto crossRightBottom = [&](ll cx, ll cy, ll r) {
239+
bool a = abs(cx - xCorner) <= r && (cy >= 0 && cy <= yCorner);
240+
bool b = abs(cy) <= r && (cx >= 0 && cx <= xCorner);
241+
return a || b;
242+
};
243+
244+
int n = circles.size();
245+
vector<bool> vis(n);
246+
auto dfs = [&](auto&& dfs, int i) -> bool {
247+
auto c = circles[i];
248+
ll x1 = c[0], y1 = c[1], r1 = c[2];
249+
if (crossRightBottom(x1, y1, r1)) {
250+
return true;
251+
}
252+
vis[i] = true;
253+
for (int j = 0; j < n; ++j) {
254+
if (vis[j]) {
255+
continue;
256+
}
257+
auto c2 = circles[j];
258+
ll x2 = c2[0], y2 = c2[1], r2 = c2[2];
259+
if ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) > (r1 + r2) * (r1 + r2)) {
260+
continue;
261+
}
262+
if (x1 * r2 + x2 * r1 < (r1 + r2) * xCorner && y1 * r2 + y2 * r1 < (r1 + r2) * yCorner
263+
&& dfs(dfs, j)) {
264+
return true;
265+
}
266+
}
267+
return false;
268+
};
269+
270+
for (int i = 0; i < n; ++i) {
271+
auto c = circles[i];
272+
ll x = c[0], y = c[1], r = c[2];
273+
if (inCircle(0, 0, x, y, r) || inCircle(xCorner, yCorner, x, y, r)) {
274+
return false;
275+
}
276+
if (!vis[i] && crossLeftTop(x, y, r) && dfs(dfs, i)) {
277+
return false;
278+
}
279+
}
280+
return true;
281+
}
282+
};
125283
```
126284

127285
#### Go
128286

129287
```go
288+
func canReachCorner(xCorner int, yCorner int, circles [][]int) bool {
289+
inCircle := func(x, y, cx, cy, r int) bool {
290+
dx, dy := x-cx, y-cy
291+
return dx*dx+dy*dy <= r*r
292+
}
293+
294+
crossLeftTop := func(cx, cy, r int) bool {
295+
a := abs(cx) <= r && cy >= 0 && cy <= yCorner
296+
b := abs(cy-yCorner) <= r && cx >= 0 && cx <= xCorner
297+
return a || b
298+
}
299+
300+
crossRightBottom := func(cx, cy, r int) bool {
301+
a := abs(cx-xCorner) <= r && cy >= 0 && cy <= yCorner
302+
b := abs(cy) <= r && cx >= 0 && cx <= xCorner
303+
return a || b
304+
}
305+
306+
vis := make([]bool, len(circles))
307+
308+
var dfs func(int) bool
309+
dfs = func(i int) bool {
310+
c := circles[i]
311+
x1, y1, r1 := c[0], c[1], c[2]
312+
if crossRightBottom(x1, y1, r1) {
313+
return true
314+
}
315+
vis[i] = true
316+
for j, c2 := range circles {
317+
if vis[j] {
318+
continue
319+
}
320+
x2, y2, r2 := c2[0], c2[1], c2[2]
321+
if (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) > (r1+r2)*(r1+r2) {
322+
continue
323+
}
324+
if x1*r2+x2*r1 < (r1+r2)*xCorner && y1*r2+y2*r1 < (r1+r2)*yCorner && dfs(j) {
325+
return true
326+
}
327+
}
328+
return false
329+
}
330+
331+
for i, c := range circles {
332+
x, y, r := c[0], c[1], c[2]
333+
if inCircle(0, 0, x, y, r) || inCircle(xCorner, yCorner, x, y, r) {
334+
return false
335+
}
336+
if !vis[i] && crossLeftTop(x, y, r) && dfs(i) {
337+
return false
338+
}
339+
}
340+
return true
341+
}
342+
343+
func abs(x int) int {
344+
if x < 0 {
345+
return -x
346+
}
347+
return x
348+
}
349+
```
130350

351+
#### TypeScript
352+
353+
```ts
354+
function canReachCorner(xCorner: number, yCorner: number, circles: number[][]): boolean {
355+
const inCircle = (x: bigint, y: bigint, cx: bigint, cy: bigint, r: bigint): boolean => {
356+
const dx = x - cx;
357+
const dy = y - cy;
358+
return dx * dx + dy * dy <= r * r;
359+
};
360+
361+
const crossLeftTop = (cx: bigint, cy: bigint, r: bigint): boolean => {
362+
const a = BigInt(Math.abs(Number(cx))) <= r && cy >= 0n && cy <= BigInt(yCorner);
363+
const b =
364+
BigInt(Math.abs(Number(cy - BigInt(yCorner)))) <= r &&
365+
cx >= 0n &&
366+
cx <= BigInt(xCorner);
367+
return a || b;
368+
};
369+
370+
const crossRightBottom = (cx: bigint, cy: bigint, r: bigint): boolean => {
371+
const a =
372+
BigInt(Math.abs(Number(cx - BigInt(xCorner)))) <= r &&
373+
cy >= 0n &&
374+
cy <= BigInt(yCorner);
375+
const b = BigInt(Math.abs(Number(cy))) <= r && cx >= 0n && cx <= BigInt(xCorner);
376+
return a || b;
377+
};
378+
379+
const n = circles.length;
380+
const vis: boolean[] = new Array(n).fill(false);
381+
382+
const dfs = (i: number): boolean => {
383+
const [x1, y1, r1] = circles[i].map(BigInt);
384+
if (crossRightBottom(x1, y1, r1)) {
385+
return true;
386+
}
387+
vis[i] = true;
388+
for (let j = 0; j < n; j++) {
389+
if (vis[j]) continue;
390+
const [x2, y2, r2] = circles[j].map(BigInt);
391+
if ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) > (r1 + r2) * (r1 + r2)) {
392+
continue;
393+
}
394+
if (
395+
x1 * r2 + x2 * r1 < (r1 + r2) * BigInt(xCorner) &&
396+
y1 * r2 + y2 * r1 < (r1 + r2) * BigInt(yCorner) &&
397+
dfs(j)
398+
) {
399+
return true;
400+
}
401+
}
402+
return false;
403+
};
404+
405+
for (let i = 0; i < n; i++) {
406+
const [x, y, r] = circles[i].map(BigInt);
407+
if (inCircle(0n, 0n, x, y, r) || inCircle(BigInt(xCorner), BigInt(yCorner), x, y, r)) {
408+
return false;
409+
}
410+
if (!vis[i] && crossLeftTop(x, y, r) && dfs(i)) {
411+
return false;
412+
}
413+
}
414+
415+
return true;
416+
}
131417
```
132418

133419
<!-- tabs:end -->

0 commit comments

Comments
 (0)