알고리즘 문제/프로그래머스

광고 삽입 [Lv. 3]

우대비 2024. 6. 18. 10:58
반응형
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

동영상 길이, 시청된 동영상 구간, 광고 길이를 입력받을 때

어느 위치에 광고를 넣어야 효율을 최대화 할 수 있는지 찾는 문제입니다.

 

풀이 방법

모든 동영상 구간의 합을 효율적으로 구해서 최대치를 찾고 출력하면 해결되는 문제입니다.

00:00:00 부터 최대 99:59:59까지 ( 360,000 크기의 배열 ) 탐색해야하기 때문에

문제 해결을 위해서는 최적화가 필수적입니다.

시청 기록을 의미하는 logs 배열의 크기가 최대 30만이며 모든 시청 시간이 00:00:00 ~ 99:59:59 일 수 있기에

이 모든 것을 하나하나 탐색하면 절대 문제를 풀 수 없습니다.

 

이때 필요한 것이 누적합을 효율적으로 구하는 알고리즘입니다.

long dp[360000];

for (string l : logs)
{
    vector<string> log = split(l);
    int start = ttoi(log[0]); // time을 int로 변환하는 함수
    int end = ttoi(log[1]);
    dp[start]++;
    dp[end]--;
}

int v_size = ttoi(play_time);
    
for (int i = 1; i < v_size; i++)
    dp[i] += dp[i - 1];

 

모든 시청 기록의 시작 지점과 끝 지점에 ++, --로 체크만 해두고

누적해서 더해 나가면 해당 시간대의 시청시간을 빠르게 저장할 수 있습니다.

 

또한 광고 길이 만큼 구간의 합을 찾아서 비교해야 하는데

이 부분에서도 광고 길이만큼 탐색하면 시간이 많이 소모됩니다.

long sum = 0;    
for (int i = 0; i < a_size; i++)
    sum += dp[i];
        
int answer = 0;
long max_sum = sum;
for (int i = a_size; i < v_size; i++)
{
    sum -= dp[i - a_size];
    sum += dp[i];

    if (max_sum < sum)
    {
        answer = i - a_size + 1;
        max_sum = sum;
    }
}

구간에서 벗어난 기록은 지우고 구간에 새로 추가된 기록은 합하는 방식으로

N의 속도로 해결했습니다.

 

정답 코드

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int ttoi(string time)
{
    int ret = 0;

    ret += time[7] - '0';      // 1초
    ret += (time[6] - '0')* 10; // 10초
    
    ret += (time[4] - '0') * 60; // 1분
    ret += (time[3] - '0') * 600; // 10분
    
    ret += (time[1] - '0') * 3600; // 1시간
    ret += (time[0]- '0') * 36000; // 10시간
    
    return ret;
}

string itot(int time)
{
    string ret;
    
    ret += to_string(time / 36000);
    time %= 36000;
    
    ret += to_string(time / 3600);
    time %= 3600;
    
    ret += ":";
    
    ret += to_string(time / 600);
    time %= 600;
    
    ret += to_string(time / 60);
    time %= 60;
    
    ret += ":";
    
    ret += to_string(time / 10);
    time %= 10;
    
    ret += to_string(time);
    
    return ret;   
}

vector<string> split(string str)
{
    vector<string> ret;
    string s;
    for (auto c : str)
    {   
        if (c == '-')
        {
            ret.push_back(s);
            s = "";
            continue;
        }
        s += c;
    }
    ret.push_back(s);
    return ret;
}

long dp[360000];
string solution(string play_time, string adv_time, vector<string> logs) {  
    for (string l : logs)
    {
        vector<string> log = split(l);
        int start = ttoi(log[0]);
        int end = ttoi(log[1]);
        dp[start]++;
        dp[end]--;
    }
  
    int v_size = ttoi(play_time);
    int a_size = ttoi(adv_time);
    
    for (int i = 1; i < v_size; i++)
        dp[i] += dp[i - 1];
    
    long sum = 0;    
    for (int i = 0; i < a_size; i++)
        sum += dp[i];
    
    int answer = 0;
    long max_sum = sum;
    for (int i = a_size; i < v_size; i++)
    {
        sum -= dp[i - a_size];
        sum += dp[i];
        
        if (max_sum < sum)
        {
            answer = i - a_size + 1;
            max_sum = sum;
        }
    }
    
    
    return itot(answer);
}

 

 

 

 

반응형
LIST

'알고리즘 문제 > 프로그래머스' 카테고리의 다른 글

합승 택시 요금 [Lv. 3]  (0) 2024.06.19
사라지는 발판 [Lv. 3]  (1) 2024.06.18
양과 늑대 [Lv. 3]  (0) 2024.06.14
파괴되지 않은 건물 [Lv. 3]  (0) 2024.06.13
행렬과 연산 [Lv. 4]  (0) 2024.06.11