def solution(play, adv, logs):
to_seconds = lambda time_: sum([int(x)*y for x, y in zip(time_.split(':'), [3600, 60, 1])])
split = lambda times_ : times_.split('-')
play, adv = to_seconds(play), to_seconds(adv)
logs = sorted([s for start, end in map(split, logs) for s in [(to_seconds(start), 1), (to_seconds(end), -1)]])
viewers, cur_time, viewers_list = 0, 0, [0] * play
for log, state in logs:
if viewers > 0:
viewers_list[cur_time:log] = [viewers] * (log - cur_time)
viewers, cur_time = viewers + state, log
adv_filter, adv_start_time = (s := sum(viewers_list[:adv]), 0)
for i, j in zip(range(play - adv), range(adv, play)):
s += viewers_list[j] - viewers_list[i]
if s > adv_filter:
adv_filter, adv_start_time = s, i + 1
return f"{adv_start_time//3600:02d}:{adv_start_time%3600//60:02d}:{adv_start_time%60:02d}"
code by 윤응구
풀이
각 시간대별 누적 시청자 수를 구한다.
광고시간 필터를 이동시키며 가장 큰 광고비용을 구한다.
시청 시간 logs
에서 각각의 point
의 정보를 뽑아낸다
(time, status)
- status(1) : 시청 시작
- status(-1) : 시청 종료
이렇게 뽑아낸 특정 시간에서의 시청 상태를 가지고 뒷 point
에 status
를 더해 주는 것으로 누적 시청자 수를 구할 수 있다.
이 누적 시청자 수를 타임라인형식으로 표현해 보면 각 index
시간에 시청자수가 몇명인지 알 수 있다.
최대 수익을 낼 수 있는 광고 시작시간은 filter
를 이용해서 구할 것이다.
adv
크기의filter
를0
~play-adv-1
까지 옮겨가며 과고 수익을 구한다.
- 핵심은 구간 크기만큼의
sum
을 구하는 것이아닌, 양끝에 수를 더하고 빼주며 합을 구해가는 것(안그러면 시간초과)
이런 식으로 filter
의 양 끝수만 바꿔줘가며 광고수익을 계산해 가장 높은 광고 수익이 나는 시간을 구한다.