본문 바로가기
Algorithm/note

[2019 KAKAO BR] 무지의 먹방 라이브

by akatapata 2022. 1. 27.

무지의 먹방 라이브

  • 회전판에 N개의 음식이 있고 음식에는 1~N의 번호가 주어진다
  • 음식은 전부 섭취하는데 일정 시간이 소요된다, food_times 배열에 들어있는시간
  • 음식 하나를 1초동안 섭취하고 남은 음식은 남겨둔다
  • k초 후에 먹어야 하는 음식을 리턴, 없으면 -1 리턴
  • 1<=len(food_times)<=200,000
  • 1<=food_times[n]<=100,000,000
  • 1<= k <= 2 x 10^13

Solution

  • 모든 음식을 먹는데 걸리는 총 시간과 k가
    같거나 큰 경우에는 불가능. -1 리턴
    if k >= sum(food_times) : return -1
  • food_times를 (걸리는시간, 음식 번호)원소의 리스트로 변경
    food_times = [(val,i+1) for i,val in enumerate(food_times)]
  • 먹는 시간이 가장 짧은 음식을 먹는데 t 시간이 걸리고, 음식 개수가 n개인 경우
  • k > t * n 인 경우
    food_times 와 k가 다음인 경우와 결과가 동일
    food_times = [ (val-t, i) for val,i in food_times if val-t > 0 ]
    k = k - t * n
  • k <= t * n 인 경우
    i = int(k%len(food_times))
    return food_times[i][1]
  • 리스트의 각 요소에 t 시간을 빼는 대신 t를 변수에 저장
  • 시간이 0이 된 요소를 제거한 list를 생성하는 대신
    시간 순으로 정렬한뒤, 시간이 짧은 음식부터 처리하고
    남은 음식의 개수를 갱신

Code1

def solution(food_times, k):

    # 전체 음식 용량이 k와 같거나 작은경우
    if k >= sum(food_times) : return -1

    # (시간,음식번호)
    food_times = [(val,i+1) for i,val in enumerate(food_times)]
    # 시간이 적게 걸리는 음식으로 sorting()
    food_times.sort()

    # 전체 음식 개수
    food_num = len(food_times)
    # 남은 음식 개수
    food_left = food_num

    # 전 단계에서 이미 소비된 시간을 중복해서 빼지 않기위한 변수
    base = 0

    for val, i in food_times:
        # skip 의 시간을 소요하면 val 시간이 걸리는 음식까지는 모두 먹은것으로 처리
        skip = (val - base) * food_left
        if k < skip : break

        k -= skip
        base = val
        food_left-=1

    food_times = food_times[food_num-food_left:].copy()
    food_times.sort(key=lambda x : x[1])
    idx = int(k%food_left)

    return food_times[idx][1]

Solution2

  • 남은 시간이 가장 적은 음식을 가져올때, 우선순위 큐 자료구조를 사용할수 있음

Code2

import heapq

def solution(food_times, k):

    # 전체 음식 용량이 k와 같거나 작은경우
    if k >= sum(food_times) : return -1

    # (남은 시간,음식번호)
    food_times = [(val,i+1) for i,val in enumerate(food_times)]
    heapq.heapify(food_times)

    # 전체 음식 개수
    food_num = len(food_times)
    # 남은 음식 개수
    food_left = food_num        
    # 전 단계에서 이미 소비된 시간을 중복해서 빼지 않기위한 변수
    base = 0

    while True:
        skip = (food_times[0][0]-base) * food_left
        if k < skip : break                                    
        k -= skip
        base = heapq.heappop(food_times)[0]
        food_left-=1

    food_times.sort(key=lambda x : x[1])
    idx = int(k%food_left)

    return food_times[idx][1]

시간복잡도

  • O(N) - sum
  • O(N) - for
  • O(N) - heapify
  • O(NlogN) - while(heappop)
  • O(NlogN) - sort

'Algorithm > note' 카테고리의 다른 글

[2019 KAKAO BR] 후보키  (0) 2022.02.03
[2019 KAKAO BR] 오픈채팅방  (0) 2022.01.27
[2019 KAKAO BR] 실패율  (0) 2022.01.27