ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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. 1에서 구한 배열을 누적합을 만들어 특정 초에 몇 명이 시청하는지 구하기
    3. 2번에서 구한 누적합을 또 누적 합하여 초별 누적 시청자 수를 구한다.
    4. 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번 누적합을 진행해서 슬라이딩 윈도우로 푸는 문제이다.
    • 누접합&슬라이딩 윈도우 문제 중 내 기준 가장 어려운 문제 😢

    댓글

Designed by Tistory.