스타트 택시
문제 파악
- 최단거리로 승객을 태우고 목적지까지 이동해야한다.
- 주어진 연료 내에서 승객을 이동시켜야 한다.
접근 방법
BFS로 구현
- 최단 거리로 가장 가까운 승객을 찾는다.
- 해당 승객의 위치까지 최단거리로 이동하여 승객을 태우고, 목적지 까지 최단 거리로 이동한다.
- 주어진 연료로 모든 승객을 이동시키고 남은 연료를 반환하거나, 이동할 수 없는 경우 -1을 반환한다.
코드 구현
from collections import deque
N, M, fuel = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)]
t_x, t_y = map(int, input().split())
taxi_cord = (t_x - 1, t_y - 1)
passengers = {}
for i in range(M):
start_x, start_y, end_x, end_y = map(int, input().split())
passengers[(start_x - 1, start_y - 1)] = (end_x - 1, end_y - 1)
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 백준이 태울 승객을 고를 때는 현재 위치에서 최단거리가 가장 짧은 승객을 고른다.
# 그런 승객이 여러 명이면 그중 행 번호가 가장 작은 승객을, 그런 승객도 여러 명이면 그중 열 번호가 가장 작은 승객을 고른다.
# 택시와 승객이 같은 위치에 서 있으면 그 승객까지의 최단거리는 0이다.
def is_valid(x, y):
return 0 <= x < N and 0 <= y < N
def pick_up(target):
q = deque()
t_x, t_y = target
q.append((t_x, t_y, 0))
visited = [[False] * N for _ in range(N)]
candidates = []
min_distance = float('inf')
while q:
cur_x, cur_y, cur_d = q.popleft()
if cur_d > min_distance:
break
if (cur_x, cur_y) in passengers:
candidates.append((cur_x, cur_y))
min_distance = cur_d
for i in range(4):
n_x, n_y, n_d = cur_x + dx[i], cur_y + dy[i], cur_d + 1
if is_valid(n_x, n_y) and board[n_x][n_y] != 1 and not visited[n_x][n_y]:
q.append((n_x, n_y, n_d))
visited[n_x][n_y] = True
return candidates, min_distance
def move(target):
q = deque()
p_x, p_y = target
t_x, t_y = passengers[(p_x, p_y)]
del passengers[(p_x, p_y)]
q.append([p_x, p_y, 0])
visited = [[False] * N for _ in range(N)]
while q:
cur_x, cur_y, cur_d = q.popleft()
if cur_x == t_x and cur_y == t_y:
return (cur_x, cur_y), cur_d
for i in range(4):
n_x, n_y, n_d = cur_x + dx[i], cur_y + dy[i], cur_d + 1
if is_valid(n_x, n_y) and board[n_x][n_y] != 1 and not visited[n_x][n_y]:
q.append((n_x, n_y, n_d))
visited[n_x][n_y] = True
return (t_x, t_y), float('inf')
answer = 0
while fuel > 0 and len(passengers) != 0:
candidates, used_fuel = pick_up(taxi_cord)
if used_fuel > fuel or len(candidates) == 0:
answer = -1
break
next_target = sorted(candidates)[0]
fuel -= used_fuel
taxi_cord, used_fuel = move(next_target)
if used_fuel > fuel:
answer = -1
break
fuel += used_fuel
if answer == -1:
print(-1)
else:
print(fuel)
배우게 된 점
항상 문제를 잘 읽고 조건을 잘 봐야한다. 백준 문제는 틀리면 반례 찾기가 어렵다. 그렇기 때문에 문제를 유심히 읽어보고 조건을 파악하여 구현을 하는 능력을 더 발전시켜야 한다.
Leave a comment