https://school.programmers.co.kr/learn/courses/30/lessons/133501
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
package study.algorithms.programers.level2.야간술보행;
public class Solution {
public int solution(int distance, int[][] scope, int[][] times) {
int answer = distance;
int soldierSize = scope.length;
//index 조정 혼돈되서 index 0 버림)
int[] table = new int[distance+1];
for (int i = 0; i < soldierSize; i++) {
int min = Math.min(scope[i][0],scope[i][1]);
int max = Math.max(scope[i][0],scope[i][1]);
for(int j = min; j <= max; j++){
if(j % (times[i][0] + times[i][1]) == 0) {
continue;
}
if((j % (times[i][0] + times[i][1])) <= times[i][0]){
table[j]=1;
break;
}
}
}
for (int i =1; i <table.length; i++) {
if(table[i]==1) return i ;
}
return answer;
}
}
1. 해당문제에서 거리는 중요하지 않다.
2. 중요한 것은 시간이다. 해당 지점에 도달 했을때 몇초이냐는것이다.
3. 예를 들어 경계구역인 "3"지점에 도달 했을때 3초의 시간이 소요되었다. 해당 경계구역이 지금 근무시간인지 휴식시간인지를 알아내야한다. 다르게 말하면 경비병의 근무구역이 아닌 곳은 생각할 필요도 없다.
먼저 정답을 위한 table을 만든다. 왜냐하면 3~4에서 걸릴 수 도 있고 5~8에서 걸릴 수도 있기 때문이다. 이중 가장 먼저 걸린쪽을 출력하기 위해 table을 만든다.
4. 예를들어 경계구역이 [5,8], 시간[3,4]라고 생각해보자 근무시간이 3 휴식시간이 4이다.
5에 도달 했을때 이곳이 휴식시간인지 아닌지 알아야한다. 이를 알기위해서는 근무 시간의 비율을 이용하면된다.
근무시간이 3 휴식이 4이면 총 7시간으로 루틴이 돌고 있다.
[근무시간 : 3, 휴식시간 : 4],[근무시간 : 3, 휴식시간 : 4],[근무시간 : 3, 휴식시간 : 4]
이를 이용하면된다.
현재 도달한 구역은 5이다. 방금 말했듯이 중요한건 도달한 시간이다. 문제에서 제시한 시간은 1m/s이기 때문에 5초가 걸렸다.
그렇다면 현재 출발로 부터 5초 경비병의 루틴으로 보면 휴식시간에 해당된다. 즉
[야간전술보행시간 : 5초] % [경비병의 루틴(근무시간 : 3 + 휴식시간 : 4)]를 하였을때 즉 나머지 값이
0이면 휴식시간의 끝 4에 걸리는 것이기 때문에 해당 구역은 통과.
근무시간보다 작거나 같으면 근무시간때에 들어간 것이기 때문에 적발
근무시간보다 크다면 휴식시간에 들어가기 때문에 통과이다.
이러한 로직으로 scope를 모두 연산하여 table을 채운다. 왜냐하면 해당 문제에서는 scope를 정렬해주지 않았다.
만약 distance가 10이라면
0001010000와 같은 table이 생성 될 수도 있다.
그렇다면 가장 앞에 있는 4를 출력하면 되는 것이다. 뒤에있는 수는 알바아니다. 어처피 앞에서 걸렸는데 뒤에 있는 값이 무슨 의미가 있겠는가.