코딩 테스트/백준
[Python] 백준 14940 쉬운 최단거리
위시리
2025. 2. 5. 18:49
문제 분석
- 주어진 지도의 각 지점에 대해 모든 목표 지점까지의 거리를 구하라
- 0 : 갈 수 없는 땅
- 1 : 갈 수 있는 땅
- 2 : 목표 지점
- 원래 갈 수 없는 땅(0)은 0 출력
- 원래 갈 수 있지만 도달할 수 없는 위치는 -1 출력
코드 설계
- 2에서의 거리를 찾아야하기 때문에 먼저 목표 지점인 2를 찾아야한다.
- 2를 기준으로 상하좌우 탐색
- 만약 이동할 수 있다면 해당 위치에 대한 거리로 바꾸고
- 이동하지 못한다면 0 그대로
- 도달할 수 없는 위치 == 0으로 둘러쌓인 곳
- bfs 상하좌우
- 원래 갈 수 있지만 도달할 수 없는 위치 → 더 이상 갈 수 잇는 곳이 없는데 아직 탐색을 다 하지 않은 경우
- 만약 현재 위치에서 더 이상 이동할 수 없거나 다 확인을 했으면 큐에 넣기
정답 코드
1차 - 실패
import sys
from collections import deque
input = sys.stdin.readline
n, m = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(n)]
d = deque()
ans = g
check = [[False] * m for _ in range(n)] # 거리를 또 계산하지 않기 위해
# 2찾기
for r in range(n):
for c in range(m) :
if g[r][c] == 2 :
ans[r][c] = 0
d.append((r,c,0))
check[r][c] = True
break
dh = [-1, 1, 0, 0]
dw = [0, 0, -1, 1]
for r in range(n) :
for c in range(m) :
if len(d) == 0 : # 여기에 걸린다는 것은 어딘가에 길이 막혀 더이상 갈 수 없다는 것
break
h, w, distance = d.popleft()
cnt = 0
for i in range(4) :
cnt += 1
nh = h + dh[i]
nw = w + dw[i]
if nh < 0 or nh >= n or nw < 0 or nw >= m :
continue
if g[nh][nw] == 0 : # 방문할 수 없는 거리
continue
if check[nh][nw] : # 방문했던 곳이면 continue
continue
# 이동한 자리에 거리에 대한 값으로 바꾸기
distance += 1
ans[nh][nw] = distance
check[nh][nw] = True
d.append((nh, nw, distance))
# 도달하지 못한부분은 -1
for i in range(n) :
for j in range(m):
if not check[i][j] and ans[i][j] != 0:
ans[i][j] = -1
for i in range(len(ans)) :
for j in range(len(ans[0])) :
print(ans[i][j], end = ' ')
print()
이 코드는 bfs가 아니라 dfs..
0에서 이동할 수 있는 칸이 있으면 이동해서 거기서 거리를 구하는 이슈가 발생
2차
- 거리 계산을 이전 위치에 대하여 +1의 거리
- 굳이 한번 싹 돌면서 -1로 바꿔주지 않고 갈 수 있는 길인데 아직 방문하지 않았다면 -1을 출력
import sys
from collections import deque
input = sys.stdin.readline
n, m = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(n)]
q = deque()
visited = [[False] * m for _ in range(n)] # 거리를 또 계산하지 않기 위해
ans = [[0]*m for _ in range(n)]
dh = [-1, 1, 0, 0]
dw = [0, 0, -1, 1]
# 시작점 찾기
for r in range(n) :
for c in range(m) :
if g[r][c] == 2 :
visited[r][c] = True
q.append((r,c))
while q :
h, w = q.popleft()
for i in range(4) :
nh = h + dh[i]
nw = w + dw[i]
if nh < 0 or nh >= n or nw < 0 or nw >= m:
continue
if g[nh][nw] != 1 : # 방문할 수 없는 거리
continue
if visited[nh][nw]: # 방문했던 곳이면 continue
continue
q.append((nh, nw))
visited[nh][nw] = True
ans[nh][nw] = ans[h][w] + 1 # 이전 거리 +1 ****
for i in range(n) :
for j in range(m) :
if not visited[i][j] and g[i][j] == 1 : # ****
print(-1, end=" ")
else :
print(ans[i][j], end = ' ')
print()