풀이전략
- 예제 1번을 통해 이해후, 작은 범위로 축소하는 것이 필요하다.
- 가장 작은 단위인 초로 변경해야 한다.
- 광고시간의 막대기 처음에 설정할때 제한 사항이 30만이고,
광고시간의 길이가 100시간 즉 360000 일때 값이 너무 크다라는 것을 인지하고
long long을 사용해야 한다.
- 막대기를 오른쪽으로 순차적으로 진행하는 것이 아니라,,, for문을 계속 돌리면서
확인하는 방법이 아님! -> 비효율적이다.
맨 뒤에서 컨테이너 한 칸을 추가하고, 맨 앞의 컨테이너를 제거하는 방식으로 진행하는 것이 효율 적이다.
소스코드
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int convert(string time)
{
stringstream ss(time);
int h, m, s;
char tmp;
ss >> h >> tmp >> m >> tmp >> s;
return h * 60 * 60 + m * 60 + s;
}
string solution(string play_time, string adv_time, vector<string> logs) {
int playSec = convert(play_time);
int advSec = convert(adv_time);
//0초부터 1초까지를 0번 인덱스로 사용
//1초부터 2초까지를 1번 인덱스로 사용
//100시간을 초단위로 잘게 잘라서 저장공간을 만들어 놓자.
int totalSec[100 * 3600] = {0};
for(string log : logs)
{
//시작 시간과 종료 시간을 나뉘어서 처리하자.
int start = convert(log.substr(0,8));
int end = convert(log.substr(9,8));
//시작시간 초 부터 종료시간 초까지 반복문 돌리면서 단위테이블을 누적시키자.
for(int i = start; i < end; i++)
{
totalSec[i] += 1;
}
}
//단위 테이블을 기준으로 하고 광고시간 크기만큼 막대기를 오른쪽으로 나아가는 상황
//최대 log값 , 즉 시청자 수가 30만이다 라는 점
//만약에 0초에서 30만이 동시에 본다면
//최대 케이스의 경우 로그 300000명이 360000초동안 시청할 때에,
//300000*360000 으로 1000억이 넘어가 int 범위를 크게 벗어나게 됩니다.
//long long을 해야 17번 테스트 케이스 통관된다.
//초기값. : 0초부터 광고 시간가지의 값.
long long curSum = 0;
for(int i = 0; i < advSec; i++)
{
curSum += totalSec[i];
}
//광고 시간 막대기를 오른쪽으로 이동하면서 max값이 나오는 값을 찾자.
long long maxSum = curSum;
//max일때의 인덱스 번호는?
int maxIdx = 0;
//막대기를 그냥 오른쪽으로 진행하는 것이 아님
//끝에 있는 것을 더하고 앞에 것을 빼는 식으로 진행하자.
for(int i = advSec; i < playSec; i++)
{
//막대기 오른쪽으로 이동하는 부분
//0번째 인덱스 부터 빼는 식으로
curSum = curSum + totalSec[i] - totalSec[i - advSec];
//최대값 갱시하는 부분
if(curSum > maxSum)
{
maxSum = curSum;
maxIdx = i - advSec + 1;
}
}
//변환을 편하게 하기 위해 sprintf를 사용하자.
char buf[10];
sprintf(buf, "%02d:%02d:%02d", maxIdx / 3600, maxIdx / 60 % 60 ,
maxIdx % 60);
string answer = buf;
return answer;
}