백준 15810번 프린터 큐

풍선 공장

문제

여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 Queue 자료구조에 쌓여서 FIFO - First In First Out - 에 따라 인쇄가 되게 된다. 하지만 상근이는 새로운 프린터기 내부 소프트웨어를 개발하였는데, 이 프린터기는 다음과 같은 조건에 따라 인쇄를 하게 된다.

현재 Queue의 가장 앞에 있는 문서의 ‘중요도’를 확인한다.
나머지 문서들 중 현재 문서보다 중요도가 높은 문서가 하나라도 있다면, 이 문서를 인쇄하지 않고 Queue의 가장 뒤에 재배치 한다. 그렇지 않다면 바로 인쇄를 한다.
예를 들어 Queue에 4개의 문서(A B C D)가 있고, 중요도가 2 1 4 3 라면 C를 인쇄하고, 다음으로 D를 인쇄하고 A, B를 인쇄하게 된다.

여러분이 할 일은, 현재 Queue에 있는 문서의 수와 중요도가 주어졌을 때, 어떤 한 문서가 몇 번째로 인쇄되는지 알아내는 것이다. 예를 들어 위의 예에서 C문서는 1번째로, A문서는 3번째로 인쇄되게 된다.

입력

첫 줄에 테스트케이스의 수가 주어진다. 각 테스트케이스는 두 줄로 이루어져 있다.

테스트케이스의 첫 번째 줄에는 문서의 개수 N(1 ≤ N ≤ 100)과, 몇 번째로 인쇄되었는지 궁금한 문서가 현재 Queue에서 몇 번째에 놓여 있는지를 나타내는 정수 M(0 ≤ M < N)이 주어진다. 이때 맨 왼쪽은 0번째라고 하자. 두 번째 줄에는 N개 문서의 중요도가 차례대로 주어진다. 중요도는 1 이상 9 이하의 정수이고, 중요도가 같은 문서가 여러 개 있을 수도 있다.

출력

각 테스트 케이스에 대해 문서가 몇 번째로 인쇄되는지 출력한다.

나의 풀이

뭔가 이 문제를 잘 이해하고나서 이분탐색이라는것에 접근하기가 쉬워졌다고 생각한다.

주의할점은, "이분탐색" 이라는것은 최대 혹은 최소에서 서서히 내려오거나 올라가는게 아니라, 정말 왔다갔다 하면서 찾는것이다.

즉, 당장은 정답(근사치)에서 멀어지는 방법이 결국 멀리서봤을때는 정답에 가까운 방법임.

우선 풍선이 다 만들어지는 "최소" 시간을 출력하는것이기때문에, 정말 적어도 주어진 풍선을 만드는 시간의 최솟값 x M 보다는 시간이 같거나 적게 걸릴것이다.

극단적으로 예를 들어보면, N이 3, M이 10 이고 3명의 스태프들이 풍선 하나를 만드는데 걸리는 시간이 다음처럼 주어진다고 가정해보자.
100, 100, 3

그렇다면 아무런 과정이 없어도 min(시간들) x M, 즉 30분보다는 같거나 적게걸린다는것을 알수있음.

때문에, min을 1로, high를 min(time)*M 로 설정하면서 이분탐색을 진행하였다.

그리고 while문에서 한바퀴 돌때마다, 현재 mid 값으로 풍선을 만드는데 걸리는 시간들을 다 나눠보면서, 실제 만들수있는 풍선의 값과 문제에서 주어진 M값을 비교하면서 low, high값을 재설정해주었다.

코드

import sys

input = sys.stdin.readline
N, M = map(int, input().strip().split())

time = list(map(int, input().strip().split()))

low, high = 1, min(time)*M

while low <= high:
    mid = (low + high) // 2
    ballons = 0
    for i in range(N):
        ballons  = ballons + (mid // time[i])

    if ballons < M:
        low = mid + 1
    elif ballons >= M:
        high = mid - 1
print(low)
profile
일단 배우는거만 정리해보자 차근차근,,

0개의 댓글