본문 바로가기

알고리즘 관련/Programmers

추석 트래픽

 

programmers.co.kr/learn/courses/30/lessons/17676

 

코딩테스트 연습 - [1차] 추석 트래픽

입력: [ "2016-09-15 20:59:57.421 0.351s", "2016-09-15 20:59:58.233 1.181s", "2016-09-15 20:59:58.299 0.8s", "2016-09-15 20:59:58.688 1.041s", "2016-09-15 20:59:59.591 1.412s", "2016-09-15 21:00:00.464 1.466s", "2016-09-15 21:00:00.741 1.581s", "2016-09-1

programmers.co.kr

추석 트래픽 문제를 풀이한다.

접근 방법이 떠오르지 않아 힌트를 참고하였는데, 핵심은 구간을 어떻게 판정해야 하는가이다.

먼저, 문자열로 된 시각들을 1초의 구간에 포함되는 확인하기 위해, 변환하는 과정이 필요하다. 여기서 double, int로 해도 되지만, 혹시나 오버플로가 날까봐 long long으로 하였다.

이 때, 시작 시각과 끝 시각을 구하여 vector로 관리하는데, 끝 시각을 이용하여 시작 시간을 구할 때 +1을 해준다.

이렇게 하는 이유는 처리 시간의 기준이 시작 시간과 끝 시간을 포함하기 때문이다.

 

위의 과정을 수행하면 vector에는 시작, 끝 시간이 포함되어 있을 것이다. 여기서 방법이 여러 가지로 나뉘는데,

첫 번째는 슬라이딩 윈도우로 각 로그마다 1초 구간에 있는 로그들을 카운트한다.

그런데 기준점을 잘 잡아야 하는데 시점에서부터 미래 혹은 과거까지의 1초인지에 따라 정답여부가 갈린다.

두 번째는 더 간단한 방법인데, 입력 조건에서 응답 완료 시간을 기준으로 오름차 정렬된 값들이 들어오기 때문에,

v[n + 1].start < v[n].end + 1000(ms)라면, 1초 내의 구간에 포함된다.

즉 코드로 나타내면 다음과 같다.

for(int i = 0; i < window.size(); i++){
        int count = 0;
        long long wend = window[i].second + 1000;
        for(int j = i; j < window.size(); j++){
            if(wend > window[j].first)
                count++;
        }
        answer = max(answer, count);
    }

정답 코드

더보기
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
vector<string> startv;
vector<pair<long long, long long>> window;
int get_ms_dur(string& str)
{
    int total = 0;
    int digit = 1000;
    for(int i = 0; i < str.size(); i++){
        if('0' <= str[i] && str[i] <= '9'){
            total += (str[i] - '0') * digit;
            digit /= 10;
        }
    }
    return total;
}
int solution(vector<string> lines) {
    int answer = 0;
    for(const auto& str : lines){
        string hour = str.substr(11, 2);
        string min = str.substr(14, 2);
        string sec = str.substr(17, 2);
        string ms = str.substr(20, 3);
        long long end = stoi(hour) * 3600 + stoi(min) * 60 + stoi(sec);
        end *= 1000;
        end += stoi(ms);
        
        string dur = str.substr(24);
        long long start = end - get_ms_dur(dur) + 1;
        window.push_back({start, end});
    }
    for(int i = 0; i < window.size(); i++){
        int count = 0;
        long long wend = window[i].second + 1000;
        for(int j = i; j < window.size(); j++){
            if(wend > window[j].first)
                count++;
        }
        answer = max(answer, count);
    }
    return answer;
}

'알고리즘 관련 > Programmers' 카테고리의 다른 글

징검다리 건너기  (0) 2021.03.05
합승 택시 요금  (0) 2021.03.02
소수 만들기  (0) 2021.02.16
가장 큰 정사각형  (0) 2021.02.10
구명보트  (0) 2021.02.08