새소식

PS/백준

[백준/1826] 연료 채우기 (Python)

  • -

Problem : https://www.acmicpc.net/problem/1826

 

1826번: 연료 채우기

첫째 줄에 주유소의 개수 N(1 ≤ N ≤ 10,000)가 주어지고 두 번째 줄부터 N+1번째 줄 까지 주유소의 정보가 주어진다. 주유소의 정보는 두개의 정수 a,b로 이루어 져 있는데 a(1 ≤ a ≤ 1,000,000)는 성경

www.acmicpc.net

 

Difficulty : Gold 2

 

Status : Solved

 

Time : 00:15:06

 


 

문제 설명

 

더보기

 

성경이는 트럭을 정글 속에서 운전하다가 트럭의 연료탱크에 갑자기 구멍이 나서 1km를 가는데 1L의 연료가 새 나가게 되었다. 이것을 고치기 위해서는 가장 가까운 마을에 가야 한다. 그런데 그냥 가다가는 중간에 연료가 다 빠질 수가 있다. 다행스럽게도 정글 곳곳에 연료를 채울 수 있는 주유소가 N개 있다. 그런데 정글 속에서 중간에 차를 멈추는 행위는 매우 위험한 행위이므로 주유소에서 멈추는 횟수를 최소화 하려 한다.

그리고 다행이도 성경이의 트럭은 매우 좋아서 연료 탱크에는 연료의 제한이 없이 많이 충분히 많이 넣을 수 있다고 한다. 각각의 주유소의 위치와, 각 주유소에서 얻을 수 있는 연료의 양이 주어져 있을 때, 주유소에서 멈추는 횟수를 구하는 프로그램을 작성하시오.

정글은 일직선이고, 성경이의 트럭과 주유소도 모두 일직선 위에 있다. 주유소는 모두 성경이의 트럭을 기준으로 오른쪽에 있다.

 

 

입력 및 출력

 

더보기

입력

 

첫째 줄에 주유소의 개수 N(1 ≤ N ≤ 10,000)가 주어지고 두 번째 줄부터 N+1번째 줄 까지 주유소의 정보가 주어진다. 주유소의 정보는 두개의 정수 a,b로 이루어 져 있는데 a(1 ≤ a ≤ 1,000,000)는 성경이의 시작 위치에서 주유소 까지의 거리, 그리고 b(1 ≤ b ≤ 100)는 그 주유소에서 채울 수 있는 연료의 양을 의미한다. 그리고 N+2번째 줄에는 두 정수 L과 P가 주어지는데 L(1 ≤ L ≤ 1,000,000)은 성경이의 위치에서 마을까지의 거리, P(1 ≤ P ≤ 1,000,000)는 트럭에 원래 있던 연료의 양을 의미한다.

모든 주유소와 마을은 서로 다른 좌표에 있고, 마을은 모든 주유소보다 오른쪽에 있다.

 

출력

 

첫째 줄에 주유소에서 멈추는 횟수를 출력한다. 만약 마을에 도착하지 못할경우 -1을 출력한다.

 

입력 예시

4
4 4
5 2
11 5
15 10
25 10

 

출력 예시

 

3

 

 


 

풀이

 

그리디하게 생각해보자. (원래 연료량 + 주유 연료량) P로 다음 주유소 i에 도착하였을 때, 만약 주유소까지의 거리 li보다 P가 부족한 경우를 생각해 볼 수 있다. 이 때는 어떻게 해야 할까? 이미 주유한 주유소를 제외하고 가장 주유량이 큰 주유소에서 연료를 공급받아야 한다. 즉 우선순위 큐(힙)를 사용하면 편하다. 주유소까지의 거리를 만족할 때까지 우선순위 큐에서 주유 연료를 pop하고, 모든 과정 뒤에는 현재 주유소의 연료량을 큐에 삽입한다. O(NlogN)의 시간복잡도 내에 풀이 가능하다.

 

만약 모든 우선순위 큐의 주유량을 썼음에도 다음 주유소에 도달하지 못한다면 -1을 출력해야 하며, 마지막 주유소를 통과하였을 때 이 트럭이 마을에 도달할 수 있는지 여부를 검사하기 위해 (마을 좌표, 주유량 0)의 데이터를 추가적으로 삽입하였다. 또한, 주유소 목록은 정렬이 보장되지 않았으므로 거리순, 주유량순으로 정렬이 필요하다.

 

풀이 코드

from heapq import heappush, heappop
import sys
input = sys.stdin.readline

N = int(input())
oil_list = [list(map(int, input().split())) for _ in range(N)]
oil_list.sort( key = lambda x : (x[0], -x[1]))
L, P = map(int, input().split())
oil_list.append([L, 0])
oil_heap = list()
cnt = 0

for l, p in oil_list :
  if P >= L :
    break
  while P < l and oil_heap :
    P += -heappop(oil_heap)
    cnt += 1
  if P < l :
    break
  heappush(oil_heap, -p)

print(cnt if P >= L else -1)

풀이 완료!

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.