알고리즘/문제풀이
[Python] Programmers 광고 삽입
정찡이
2021. 7. 17. 21:17
728x90
1. 문제 링크
코딩테스트 연습 - 광고 삽입
시간을 나타내는 HH, H1, H2의 범위는 00~99, 분을 나타내는 MM, M1, M2의 범위는 00~59, 초를 나타내는 SS, S1, S2의 범위는 00~59까지 사용됩니다. 잘못된 시각은 입력으로 주어지지 않습니다. (예: 04:60:24, 11
programmers.co.kr
2. 문제 요약
시청자들의 누적 재생시간이 가장 많은 곳 찾기 ⇒ 누적합으로 구하기
[입력값]
- play_time: 동영상 끝나는 시간
- adv_time: 공익광고 재생 시간
- logs: 시청자들 시청하는 구간
[리턴 값]
- 광고 삽입할 시작 시간 - HH:MM:SS (str)

3. 아이디어 정리
누적합으로 해당 구간에 몇 명이 시청하는지 구한다.
- 초 단위 별로 시청 시작 시각에는 + 1시청 끝 시각 -1 저장한다.
- 1에서 구한 배열을 누적합을 만들어 특정 초에 몇 명이 시청하는지 구하기
- 2번에서 구한 누적합을 또 누적 합하여 초별 누적 시청자 수를 구한다.
- 3번에서 구한 결과를 슬라이딩 윈도우를 통해 특정 기간에 몇 명이 시청하는지 찾아 최대 시청하는 시작 시간을 구한다.

4. 문제 풀이
4-1. 내 풀이
"""
슬라이딩 윈도우
부분합 - 시작과 종료를 담는 부분합
"""
def get_second(time):
h, m, s = time.split(":")
return int(h) * 3600 + int(m) * 60 + int(s)
def get_log_time(adv):
s, e = adv.split("-")
return (get_second(s), get_second(e))
def get_str_time(seconds):
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
return '{:02d}:{:02d}:{:02d}'.format(h, m, s)
def solution(play_time, adv_time, logs):
"""
시청자들의 누적 재생시간이 가장 많은 곳 찾기
:param play_time: 광고 끝나는 시간
:param adv_time: 공익광고 재생시간
:param logs: 시청자들 시청하는 구간
:return: 광고 삽입할 시작 시간 - HH:MM:SS
"""
# 1. 모든 시간을 초로 변환
play_time = get_second(play_time)
adv_time = get_second(adv_time)
# 2. 전체 초를 배열로 담기
log_time = [0 for _ in range(play_time + 1)]
for log in logs:
start, end = get_log_time(log)
log_time[start] += 1
log_time[end] -= 1
# 2. log_time 부분합 구하기 - 특정 초에 시청되는 인원 파악
for i in range(1, len(log_time)):
log_time[i] += log_time[i - 1]
# 3. 두번째 부분합을 진행하여 누적 시청자 파악
for i in range(1, len(log_time)):
log_time[i] += log_time[i - 1]
# 4. 슬라이딩 윈도우 - 누적합으로 가장 많이 시청하는 인원 찾기
result_time = 0 # 가장 많이 시청한 시간
result_cnt = 0 # 가장 많이 시청한 사람 수
for end in range(adv_time - 1, play_time):
if end >= adv_time: # end가 광고 시간보다 커야 누적합 구하기 가능
if result_cnt < log_time[end] - log_time[end - adv_time]:
result_cnt = log_time[end] - log_time[end - adv_time]
result_time = end - adv_time + 1
else: # 광고 끝나는 시간이 광고시간보다 작은 경우
if result_cnt < log_time[end]:
result_cnt = log_time[end] # 0~end 시간 누적
result_time = 0 # 광고 삽입 시작시간: 0초
return get_str_time(result_time)
5. 결론
- 2번 누적합을 진행해서 슬라이딩 윈도우로 푸는 문제이다.
- 누접합&슬라이딩 윈도우 문제 중 내 기준 가장 어려운 문제 😢
반응형