Skip to content

Commit

Permalink
Create 아이템 줍기.md
Browse files Browse the repository at this point in the history
  • Loading branch information
borricha authored Aug 13, 2022
1 parent 4330e07 commit e35feac
Showing 1 changed file with 123 additions and 0 deletions.
123 changes: 123 additions & 0 deletions programmers/고득점 kit_BFS_DFS/아이템 줍기.md
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) 등등..

0 comments on commit e35feac

Please sign in to comment.