[BaekJoon] 백준 19238번 스타트 택시
🎈문제
https://www.acmicpc.net/problem/19238
💬설명
- 1시간 20분 걸렸다. bfs와 구현 문제
- bfs를 구현할 때 visited = True 체크를 안해준다는 등 하나씩 자꾸 빼먹는 실수를 한다. 그리고 마지막에 계속 틀렸다고 나왔는데 벽에 막혀서 승객이 목적지에 도착하지 못하는 경우도 있다는 것을 고려 안했기 때문이었다. 문제가 어설픈건지 내가 이런 조건을 생각을 못한 건지..
👩💻코드
# BaekJoon19238.py
from collections import deque
import sys
input = sys.stdin.readline
N, M, energy = map(int, input().split())
arr = [[] for _ in range(N)]
for i in range(N):
arr[i] = list(map(int, input().split()))
car = list(map(int, input().split()))
car[0] -= 1
car[1] -= 1
people = {} # arr에 표시한 승객 번호를 key로, 출발지 & 목적지 좌표를 value로
for i in range(M):
p = list(map(int, input().split()))
for j in range(4):
p[j] -= 1
arr[p[0]][p[1]] = i + 2
people[i + 2] = p
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
# 최단 거리가 가장 짧은 승객 선택 -> 행 번호 가장 작은 -> 열 번호 가장 작은
def select(x, y):
global arr, people, M, dx, dy
visited = [[False for _ in range(N)] for _ in range(N)]
selected = 0
distance = float('inf')
queue = deque([[x, y, 0]]) # x, y좌표, 차로부터의 거리
visited[x][y] = True
while queue:
v = queue.popleft()
# 해당 위치에 승객이 있다면
if arr[v[0]][v[1]] != 0 and arr[v[0]][v[1]] != 1:
if distance < v[2]: # 이미 최단 거리가 아니므로 bfs 종료
break
elif distance > v[2]: # 최단 거리인 승객 update
selected = arr[v[0]][v[1]]
distance = v[2]
elif distance == v[2]: # 행, 열 더 작은 승객 선택
tmp = sorted([[people[selected][0], people[selected][1]], [v[0], v[1]]], key=lambda x: (x[0], x[1]))[0]
selected = arr[tmp[0]][tmp[1]]
else:
for i in range(4):
nx = v[0] + dx[i]
ny = v[1] + dy[i]
if nx < 0 or ny < 0 or nx >= N or ny >= N:
continue
if not visited[nx][ny] and arr[nx][ny] != 1:
visited[nx][ny] = True
queue.append([nx, ny, v[2] + 1])
return selected, distance
# p 위치로 이동 후 p 승객의 목적지로 이동
def move(p, d):
global car, arr, energy, people, N, dx, dy
# p 승객의 출발지로 이동
# 연료가 부족하면 종료
if d >= energy:
return False
car = [people[p][0], people[p][1]]
energy -= d
# bfs로 승객의 목적지까지 최단 거리 구해서 이동
visited = [[False for _ in range(N)] for _ in range(N)]
queue = deque([[car[0], car[1], 0]])
visited[car[0]][car[1]] = True
while queue:
v = queue.popleft()
if v[0] == people[p][2] and v[1] == people[p][3]: # 승객의 목적지에 도착했다면
# 연료 체크
if v[2] > energy:
return False
car = [v[0], v[1]]
energy = energy + v[2]
# 승객 도착했으므로 지우기
arr[people[p][0]][people[p][1]] = 0
del people[p]
return True
for i in range(4):
nx = v[0] + dx[i]
ny = v[1] + dy[i]
if nx < 0 or ny < 0 or nx >= N or ny >= N:
continue
if not visited[nx][ny] and arr[nx][ny] != 1:
queue.append([nx, ny, v[2] + 1])
visited[nx][ny] = True
return False
def solution():
global M, car, energy
for i in range(M):
p, d = select(car[0], car[1])
if not move(p, d):
print(-1)
return
print(energy)
return
solution()
728x90
반응형
'CS > Algorithm 문제' 카테고리의 다른 글
[BaekJoon] 백준 11909번 배열 탈출 (0) | 2021.11.04 |
---|---|
[BaekJoon] 백준 13913번 숨바꼭질4 (0) | 2021.10.28 |
[BaekJoon] 백준 20055번 컨베이어 벨트 위의 로봇 (0) | 2021.10.22 |
[BaekJoon] 백준 20056번 마법사 상어와 파이어볼 (0) | 2021.10.21 |
[BaekJoon] 백준 16235번 나무 재테크 (0) | 2021.10.21 |