-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
### 아이템 줍기 | ||
--- | ||
https://school.programmers.co.kr/learn/courses/30/lessons/87694# | ||
|
||
bfs 자체는 어렵지 않았는데, 좌표이동하면서 사각형 외각인점을 체크하는 부분이 빡셌다. 결국 별의별 구현을 해보다가 | ||
(도형안에 있는지 체크하고, 가면안되는 길을 가는지 체크하는 등등 함수를 다 만들어하다가) 결국 실패했다. | ||
|
||
두가지 아이디어가 필요했다. | ||
1. 좌표계를 2배로 늘리거나 중간값을 체크해서 가면 안되는 길로 가는지 체크하고 | ||
2. 상하좌우대각선의 합이 8이면(사각형 내부, 경계는다 1로 초기화시켜놈) 외곽이 아니다는 걸 체크! | ||
|
||
아래는 잘못구현한 코드이고.. | ||
```python | ||
from collections import deque | ||
def solution(rectangle, characterX, characterY, itemX, itemY): | ||
flag = [ [0 for i in range(50)] for j in range(50)] | ||
dx = [1, -1, 0, 0] | ||
dy = [0, 0, 1, -1] | ||
answer = 0 | ||
|
||
#도형의 테두리면서, 다른 도형의 안에 들어가 있지 않아야 함, 0는 못가는길, 1은 갈 수 있음 | ||
def boundary_check(x, y): | ||
#사각형 안에 있는지 check | ||
for i in rectangle: | ||
if(x > i[0] and x < i[2] and y > i[1] and y < i[3]): | ||
return 0 | ||
for i in rectangle: | ||
#테두리 이면서 | ||
if ((x == i[0] and y<=i[3] and y>=i[1]) or (x == i[2] and y<=i[3] and y>=i[1]) or (y == i[1] and x<=i[2] and x>=i[0]) or (y == i[3] and x<=i[2] and x>=i[0])): | ||
return 1 | ||
return 0 | ||
|
||
def outside_check(x,y,nx, ny): | ||
for i in rectangle: | ||
if (y>=i[1] and y<=i[3]) and (ny>=i[1] and ny<=i[3])and (x>=i[0] and x<=i[2]) and (nx>=i[0] and nx<=i[2]): | ||
return 1 | ||
return 0 | ||
#deque((x,y))는 안됨 | ||
queue = deque([(characterX, characterY)]) | ||
flag[characterX][characterY] = 1 | ||
while queue: | ||
x, y = queue.popleft() | ||
if x == itemX and y == itemY: | ||
for i in range(10): | ||
for j in range(10): | ||
print(flag[i][j], end= " ") | ||
print() | ||
return flag[x][y] - 1 | ||
for i in range(4): | ||
nx = x + dx[i] | ||
ny = y + dy[i] | ||
if nx < 0 or ny < 0 or nx >= 50 or ny >= 50: | ||
continue | ||
if flag[nx][ny] != 0: | ||
continue | ||
#사각형 밖으로 가는지 check | ||
if outside_check(x,y,nx,ny) == 0: | ||
continue | ||
|
||
if boundary_check(nx, ny) == 0: | ||
continue | ||
queue.append((nx, ny)) | ||
print(nx, ny) | ||
flag[nx][ny] = flag[x][y] + 1 | ||
|
||
``` | ||
|
||
다시 구현한 코드는 다음과 같다 | ||
```python | ||
from collections import deque | ||
def solution(rectangle, characterX, characterY, itemX, itemY): | ||
check = [ [0 for i in range(104)] for j in range(104)] | ||
for i in rectangle: | ||
for j in range(i[0]*2, i[2]*2+1): | ||
for k in range(i[1]*2, i[3]*2+1): | ||
check[j][k] = 1 | ||
|
||
visited = [ [0 for i in range(104)] for j in range(104)] | ||
dx = [1, -1, 0, 0] | ||
dy = [0, 0, 1, -1] | ||
cx = [1, -1, 0, 0, 1, 1, -1, -1] | ||
cy = [0, 0, 1, -1, 1, -1, 1, -1] | ||
answer = 0 | ||
|
||
#deque((x,y))는 안됨 | ||
queue = deque([(characterX*2, characterY*2)]) | ||
visited[characterX*2][characterY*2] = 1 | ||
while queue: | ||
x, y = queue.popleft() | ||
if x == itemX*2 and y == itemY*2: | ||
return visited[x][y] // 2 | ||
|
||
for i in range(4): | ||
nx = x + dx[i] | ||
ny = y + dy[i] | ||
if nx < 0 or ny < 0 or nx >= 104 or ny >= 104: | ||
continue | ||
if check[nx][ny] != 1: | ||
continue | ||
if visited[nx][ny] != 0: | ||
continue | ||
count = 0 | ||
for j in range(8): | ||
nnx = nx + cx[j] | ||
nny = ny + cy[j] | ||
count += check[nnx][nny] | ||
if count == 8: | ||
continue | ||
queue.append((nx, ny)) | ||
visited[nx][ny] = visited[x][y] + 1 | ||
``` | ||
이외에도 | ||
```python | ||
def is_movable(cur_x, cur_y, next_x, next_y, rectangles): | ||
x, y = (cur_x + next_x) / 2, (cur_y + next_y) / 2 | ||
is_on_any_border = any( | ||
(x in (x1, x2) and y1 <= y <= y2) or (y in (y1, y2) and x1 <= x <= x2) | ||
for x1, y1, x2, y2 in rectangles) | ||
is_inside_any_rect = any( | ||
x1 < x < x2 and y1 < y < y2 for x1, y1, x2, y2 in rectangles) | ||
return is_on_any_border and not is_inside_any_rect | ||
``` | ||
이렇게 경계를 체크한 사람도 있었다, any와 in(x1,x2) 등등.. |