일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- c++ 기초
- 백준9095
- 혁펜하임강의후기
- 백준1026
- 패스트캠퍼스
- C++ 백준
- 백준
- 1로만들기
- C++
- 패스트캠퍼스혁펜하임
- 조건문
- 비교연산자
- 반복문
- 혁펜하임AI
- AIDEEPDIVE
- pytorch
- tensorflow
- 백준1463
- C++ 공백 입력
- CUDA
- for문
- 9095
- 혁펜하임
- 혁펜하임강의
- 백준C++
- precision
- 1463
- C++ 함수
- cuDNN
- AI강의
- Today
- Total
코딩하는 덕구 🐶
137. [삼성기출33]Python 백준 19238 번 스타트 택시 자세한 설명 및 반례 본문
안녕하세요 코딩하는 덕구입니다.
파이썬 백준 19238 스타트 택시입니다.
https://www.acmicpc.net/problem/19238
19238번: 스타트 택시
첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다
www.acmicpc.net
백준 19238 스타트 택시 파이썬 코드입니다. 설명은 아래에 있습니다.
from collections import deque
N, M, fuel = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)]
x, y = map(int, input().split())
x, y = x-1, y-1
info = [list(map(int, input().split())) for _ in range(M)]
#승객 2 도착 3
index_p = {}
cord_d = {}
for num, i in enumerate(info):
x1, y1, x2, y2 = i
board[x1 - 1][y1 - 1] = 2
index_p[(x1 - 1, y1 - 1)] = num
cord_d[num] = [x2 - 1, y2 - 1]
dx = [-1, 0, 0, 1]
dy = [0, -1, 1, 0]
def solve():
global x, y, fuel
while M > 0:
x, y, fuel, destx, desty = find_passenger(x, y, fuel)
if fuel < 0:
return -1
fuel = go_destination(x, y, fuel, destx, desty)
x, y = destx, desty
if fuel < 0:
return -1
return fuel
def find_passenger(x, y, fuel):
global M
distance = 1e9
candidate = [] #승객 후보
queue = deque()
queue.append([x, y, fuel])
visited = [[False for _ in range(N)] for _ in range(N)]
visited[x][y] = True
while queue:
x, y, fuel = queue.popleft()
start = fuel
if board[x][y] == 2: #도착한 경우
if fuel >= 0:
if start - fuel <= distance:
candidate.append([x, y, fuel])
distance = start - fuel
for i in range(4):
nx, ny = dx[i] + x, dy[i] + y
if 0 <= nx < N and 0 <= ny < N:
if not visited[nx][ny] and board[nx][ny] != 1 and 0 < fuel:
visited[nx][ny] = True
queue.append([nx, ny, fuel - 1])
if candidate:
candidate.sort(key=lambda x : (-x[2], x[0], x[1]))
x, y, fuel= candidate[0]
board[x][y] = 0
M -= 1
num = index_p[(x, y)]
destx, desty = cord_d[num]
return [x, y, fuel, destx, desty]
return [-1, -1, -1, -1, -1] #갈 곳이 없는 경우
def go_destination(x, y, fuel, destx, desty):
queue = deque()
origin = fuel
queue.append([x, y, fuel])
visited = [[False for _ in range(N)] for _ in range(N)]
visited[x][y] = True
while queue:
x, y, fuel = queue.popleft()
if [x, y] == [destx, desty]:
if fuel < 0:
return -1
return fuel + (origin - fuel) * 2
for i in range(4):
nx, ny = dx[i] + x, dy[i] + y
if 0 <= nx < N and 0 <= ny < N:
if not visited[nx][ny] and board[nx][ny] != 1 and fuel > 0:
visited[nx][ny] = True
queue.append([nx, ny, fuel - 1])
return -1
print(solve())
문제 접근
1. 가장 가까운 승객을 찾기위한 BFS 1번
2. 최단 거리로 도착에 가기위한 BFS 1번
3. 위의 BFS들을 연료가 떨어지거나 모든 승객을 태울 때 까지 반복합니다.
4. 최단거리의 승객이 여러명인 경우 열과 행이 가장 작은 숫자인 승객을 태웁니다.
이때 BFS탐색을 [상, 좌, 우, 하]순으로 시도하고, 가장 먼저 만난 승객을 태우게 되면
4번의 조건을 통과하지 못합니다.
[좌, 좌, 좌], [우, 우, 상] 의 경우 1 번째 경우가 먼저 탐색이 되지만
우선순위에서 2 번째 경우가 앞서는 반례가 있습니다.
Python 코드 구현
그래프의 상태, 승객과, 도착지, 방향을 구현하기 위한 코드들을 작성합니다.
index_p의 경우 좌표를 넣으면 몇번 승객인지 알려주는 dictionary 입니다.
cord_d는 번호를 넣으면 도착 좌표를 알려줍니다.
from collections import deque
N, M, fuel = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)]
x, y = map(int, input().split())
x, y = x-1, y-1
info = [list(map(int, input().split())) for _ in range(M)]
#승객 2 도착 3
index_p = {}
cord_d = {}
for num, i in enumerate(info):
x1, y1, x2, y2 = i
board[x1 - 1][y1 - 1] = 2
index_p[(x1 - 1, y1 - 1)] = num
cord_d[num] = [x2 - 1, y2 - 1]
dx = [-1, 0, 0, 1]
dy = [0, -1, 1, 0]
1. find_passenger 를 통해 조건에 맞는 최단거리 승객을 찾습니다.
2. go_destination을 통해 최단거리로 도착지로 이동한 후 연료를 채웁니다.
3. 모든 승객을 다 태울때 까지 반복합니다.
4. 이때 연료가 다 떨어지거나 승객 혹은 도착지를 찾을 수 없으면 -1 을 return 합니다.
def solve():
global x, y, fuel
while M > 0:
x, y, fuel, destx, desty = find_passenger(x, y, fuel)
if fuel < 0:
return -1
fuel = go_destination(x, y, fuel, destx, desty)
x, y = destx, desty
if fuel < 0:
return -1
return fuel
print(solve())
조건에 맞는 최단거리의 승객을 찾는 함수 find_passenger입니다.
candidate는 승객 후보를 담는 list입니다.
승객을 찾게되면 기존보다 distance가 크지 않은지 확인 한 후, distance를 업데이트 합니다.
조건에 맞다면 cansdidate에 추가합니다.
def find_passenger(x, y, fuel):
global M
distance = 1e9
candidate = [] #승객 후보
queue = deque()
queue.append([x, y, fuel])
visited = [[False for _ in range(N)] for _ in range(N)]
visited[x][y] = True
while queue:
x, y, fuel = queue.popleft()
start = fuel
if board[x][y] == 2: #도착한 경우
if fuel >= 0:
if start - fuel <= distance:
candidate.append([x, y, fuel])
distance = start - fuel
BFS 탐색은 이렇게 진행해주시고
for i in range(4):
nx, ny = dx[i] + x, dy[i] + y
if 0 <= nx < N and 0 <= ny < N:
if not visited[nx][ny] and board[nx][ny] != 1 and 0 < fuel:
visited[nx][ny] = True
queue.append([nx, ny, fuel - 1])
탐색이 끝나면 후보가 있는지 확인 한 후
연료가 가장 많이 남고, 좌표가 작은 순으로 후보를 정렬 합니다.
이후 택시 좌표, 남은 연료, 도착 좌표를 return 합니다.
if candidate:
candidate.sort(key=lambda x : (-x[2], x[0], x[1]))
x, y, fuel= candidate[0]
board[x][y] = 0
M -= 1
num = index_p[(x, y)]
destx, desty = cord_d[num]
return [x, y, fuel, destx, desty]
return [-1, -1, -1, -1, -1] #갈 곳이 없는 경우
다음은 도착지점으로 가는 함수 go_destination입니다.
사용한 연료를 * 2를 해주어 남은 연료와 더해 연료를 업데이트 합니다.
def go_destination(x, y, fuel, destx, desty):
queue = deque()
origin = fuel
queue.append([x, y, fuel])
visited = [[False for _ in range(N)] for _ in range(N)]
visited[x][y] = True
while queue:
x, y, fuel = queue.popleft()
if [x, y] == [destx, desty]:
if fuel < 0:
return -1
return fuel + (origin - fuel) * 2
for i in range(4):
nx, ny = dx[i] + x, dy[i] + y
if 0 <= nx < N and 0 <= ny < N:
if not visited[nx][ny] and board[nx][ny] != 1 and fuel > 0:
visited[nx][ny] = True
queue.append([nx, ny, fuel - 1])
return -1
백준 19238 스타트 택시 Python 코드였습니다.
감사합니다.
'알고리즘 문제 풀이' 카테고리의 다른 글
139. [삼성기출35]Python 백준 20056 마법사 상어와 파이어볼 (0) | 2023.08.14 |
---|---|
138. [삼성기출34]Python 백준 20055 번 컨베이어 벨트 위의 로봇 자세한 설명 (0) | 2023.08.09 |
136. [삼성기출32]Python 백준 19237 번 어른 상어 (0) | 2023.08.04 |
135. [삼성기출31]Python 백준 19236 번 청소년 상어 (0) | 2023.07.21 |
134. [삼성기출30]Python 백준 20061 번 모노미도미노 2 디버그 코드 포함 (0) | 2023.07.09 |