74 lines
2.2 KiB
Python
74 lines
2.2 KiB
Python
# 쉬운 최단거리
|
|
|
|
import sys
|
|
from collections import deque
|
|
|
|
input = sys.stdin.readline
|
|
|
|
def find_target(grid, n, m):
|
|
for i in range(n):
|
|
for j in range(m):
|
|
if grid[i][j] == 2:
|
|
target = (i, j)
|
|
return target
|
|
return (-1, -1)
|
|
|
|
def set_zero_land(grid, visited, n, m):
|
|
for i in range(n):
|
|
for j in range(m):
|
|
if grid[i][j] == 0:
|
|
visited[i][j] = 0
|
|
return
|
|
|
|
|
|
def bfs(grid, target, n, m):
|
|
dr = [1, -1, 0, 0]
|
|
dc = [0, 0, 1, -1]
|
|
visited = [[-1]*m for _ in range(n)]
|
|
set_zero_land(grid, visited, n, m)
|
|
q = deque([target])
|
|
visited[target[0]][target[1]] = 0
|
|
|
|
while q:
|
|
r, c = q.popleft()
|
|
for i in range(4):
|
|
now_r, now_c = r+dr[i], c+dc[i]
|
|
if now_r == target[0] and now_c == target[1]:
|
|
continue
|
|
if 0 <= now_r < n and 0 <= now_c < m and grid[now_r][now_c] != 0 and visited[now_r][now_c] == -1:
|
|
q.append((now_r, now_c))
|
|
visited[now_r][now_c] = visited[r][c] + 1
|
|
|
|
return visited
|
|
|
|
def solution():
|
|
n, m = map(int, input().rstrip().split())
|
|
|
|
grid = [list(map(int, input().rstrip().split())) for _ in range(n)]
|
|
|
|
target = find_target(grid, n, m)
|
|
|
|
result = bfs(grid, target, n, m)
|
|
|
|
for i in range(n):
|
|
print(*result[i])
|
|
|
|
return
|
|
|
|
|
|
solution()
|
|
|
|
"""
|
|
걸린 시간: 55분
|
|
|
|
시간 복잡도: target 찾고, 0 세팅 하는데 O(nm)이고,
|
|
bfs는 한 노드마다 4번의 인접 노드를 확인하므로 O(4nm)
|
|
전체 시간복잡도는 O(nm)이다.
|
|
|
|
해설: 각 점에서 도착지까지 계속 찾아가는건 말이 안되고, 인접 점의 결과에 +1을 하는 식으로
|
|
O(1)에 찾도록 생각을 하였다. dp가 떠올랐지만,
|
|
target 지점을 기준으로 +1씩 해야하기 때문에 target이 중간 어딘가에 있으면 dp 테이블을 채우기 애매했다.
|
|
따라서 너비우선 탐색을 떠올렸고, bfs로 진행했다.
|
|
조건들이 조금 귀찮아서 몇 번 틀렸는데, 0인 땅은 그냥 0이고, 1인데 못 가는 땅은 -1로 출력을 해야했다.
|
|
따라서 bfs 세팅에서 기본 visited를 -1로 잡고, 0인 땅은 0으로 초기화 해주는 작업을 했다.
|
|
""" |