developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • SW역량테스트파이썬
  • 통계학
  • 데이터분석
  • 삼성코테자바꿀팁
  • c++ 빌더 패턴
  • 삼성코테파이썬풀이
  • 삼성코테구현문제추천
  • 코테파이썬
  • MA모형
  • 운영체제인터럽트
  • AR모형
  • 삼성코테기출자바풀이
  • 카카오코테java풀이
  • BOJ파이썬풀이
  • 삼성코테파이썬준비
  • 삼성코테파이썬
  • 삼성코테구현풀이
  • 시계열
  • 통계분석
  • SW역량테스트파이썬풀이
  • 백준파이썬풀이
  • 시계열분석
  • ARIMA모형
  • 삼성코테준비
  • 삼성코테자바준비
  • c++디자인패턴
  • Arima
  • 삼성코테자바풀이
  • 카카오코테
  • 삼성코테기출

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 스타트택시 19238번 (python)

2021. 10. 20. 14:48

❓ 문제 - 백준 스타트택시 19238번 - python 풀이법

 

출처 

(https://www.acmicpc.net/problem/19238)

 

19238번: 스타트 택시

첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다

www.acmicpc.net

 

📝 문제해결법

1. 이 문제는 BFS+구현으로 풀었다.

  • graph 이중리스트를 이용해서 벽이 있는 부분을 -1, 아무것도 없는 부분은 -2로 변경해서 저장한다.
  • cus 리스트를 이용해서 택시 고객의 현재 위치와 목적지의 위치를 저장한다.
  • while문을 통해 택시를 계속 운영하는데 만약 손님이 없다면 while을 빠져나가고, 손님이 있다면 BFS로 현재 택시의 위치에서 모든 좌표로 움직이는 거리를 계산한 후, 갈 수 있는 모든 손님이 있는 위치와 거리를 찾아 move 리스트에 넣어준다.
  • move 즉, 손님이 없거나 모두 다 손님까지 갈 수 없을 경우 while을 빠져나온다.
  • move 리스트를 정렬하는데 (거리 내림차순 - 행 내림차순 - 열 내림차순)으로 정렬한다. 0번 인덱스, 즉 가장 가까운 손님으로 이동하기 전에 연료가 부족하면 택시 운행을 종료한다.
  • 만약 손님으로 이동가능하면 다시 BFS를 돌려서 (출발-손님 현재 위치) 손님 도착 위치까지의 거리를 계산한다. 만약 갈 수 없는 곳이라면 택시 운행을 종료하고, 갈 수 있는 곳이면서 만약 연료가 부족하면 택시 운행을 종료, 연료가 충분하면 연료 - 목적지까지 거리 + 목적지까지 거리*2로 연료를 계산해준다.
  • 택시 운행을 종료할 때까지 while을 돌려준 후 남은 연료를 출력한다.

2. 문제 풀면서 느낀점

  • 문제 조건에 맞춰서 구현할 수 있어야한다.
  • 여기서 포인트는 택시가 손님을 태우고 도착지까지 가는 거리가 0일 경우도 잘 고려해야하고, 만약 손님을 태우고 가는 거리랑 현재 연료랑 같을 경우도 택시 운행을 종료하지 않는 조건을 유념해서 풀어야한다.

 

💻 소스코드

# 스타트택시 - BOJ 19238
# BFS + 구현
import copy
from collections import deque
n, m, k = map(int, input().split())
graph = []
for i in range(n):
    data = list(map(int, input().split()))
    array = []
    for d in data:
        if d == 1:
            array.append(-1)
        else:
            array.append(-2)

    graph.append(array)

dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
cus = []
t_x, t_y = map(int, input().split())
t_x -= 1
t_y -= 1
for _ in range(m):
    a, b, c, d = map(int, input().split())
    cus.append([a, b, c, d])

def cal_dis(graph, t_x, t_y):
    g = copy.deepcopy(graph)
    visited = [[False]*n for _ in range(n)]
    q = deque()
    q.append((t_x, t_y))
    g[t_x][t_y] = 0
    visited[t_x][t_y] = True
    while q:
        x, y = q.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 > nx or 0 > ny or nx >= n or ny >= n:
                continue
            if g[nx][ny] == -1 or visited[nx][ny] == True:
                continue
            g[nx][ny] = g[x][y] + 1
            visited[nx][ny] = True
            q.append((nx, ny))
    return g


while True:
    if k < 0:
        break
    if len(cus) == 0:
        break
    move = []
    g_copy = cal_dis(graph, t_x, t_y)
    # 택시 - 손님
    for c in cus:
        a, b, c, d = c
        dis = g_copy[a-1][b-1]
        if dis < 0:
            continue
        move.append([dis, a-1, b-1, c-1, d-1])
    if len(move) == 0:
        k = -1
        break
    else:
        move.sort(key=lambda x:(x[0], x[1], x[2]))
        # 손님 - 도착지
        if move[0][0] > k:
            k = -1
            break
        else:
            k -= move[0][0]
            t_x, t_y, a, b = move[0][1:]
            end = cal_dis(graph, t_x, t_y)
            d = end[a][b]
            if d < 0:
                k = -1
                break
            k -= d
            if k >= 0:
                k += (d*2)
                cus.remove([t_x+1, t_y+1, a+1, b+1])
                t_x, t_y = a, b
            else:
                k = -1
                break

print(k)

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 마법사 상어와 파이어볼 20056번 (python)  (0) 2021.10.20
BOJ - 컨베이어 벨트 위의 로봇 20055번 (python)  (0) 2021.10.20
BOJ - 어른 상어 19237번 (python)  (0) 2021.10.20
BOJ - 청소년 상어 19236번 (python)  (2) 2021.10.19
BOJ - 모노미노도미노2 20061번 (python)  (0) 2021.10.19
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 마법사 상어와 파이어볼 20056번 (python)
    • BOJ - 컨베이어 벨트 위의 로봇 20055번 (python)
    • BOJ - 어른 상어 19237번 (python)
    • BOJ - 청소년 상어 19236번 (python)
    developer-ellen
    developer-ellen

    티스토리툴바