강의로 돌아가기
supersfel

힌트 [코드ㅇ]

시침,분침,초건이 만나는 조건을 잘 생각하면 수학적으로 해결이 가능합니다.

기본적으로 1분에 초침이 한바퀴를 돌며 시침,분침 두개를 한번씩 만난다고 가정합니다.
그런데 잘생각해보면 59분 -> 00분으로 갈때는 초침과 분침이 만나지 않습니다. 59분인 경우 초침이 한바퀴를 돌아서 00분이 되는 경우에만 만나기 때문입니다.

같은 원리로 시침,초침또한 11시->12시로 이동할때는 겹치지 않습니다.

즉 59분->00분으로 갈때마다 (한시간마다) 만나는 횟수를 1씩 빼주고 12시 00분인 경우에만 특이처리를 해주면 됩니다.

[조금더 쉬운 설명]
0시0분0초 ~ 23시59분59초까지 시,분,초침이 만나는 횟수를 구한다생각해봅시다.
단순하게 하루는 24*60 = 1440분입니다. 즉, 1분당 시,분침이 초침과 1번씩 만나므로
1440 * 2 = 2880번 만난다고 가정해봅시다.
방금 말한대로 59분 -> 00분으로 갈때 분침,초침은 만나지 않습니다. 따라서 -24의 카운트를 해줍니다.
또 11시59분 -> 12시 와 23시59분 -> 00시 로갈때 시침,초침은 만나지 않습니다. 따라서 -2의 카운트를 해줍니다.
0시0분0초 , 12시0분0초는 시-분-초 침이 만나서 카운트를 하나로만 치게 됩니다. 따라서 -2의 카운트를 해줍니다.

따라서 마지막 예제의 답은 2880 - 28 = 2852가되게 됩니다.

고려해야할 점은 시작 시간과 끝나는 시점이 유동적이라는 점입니다.

따라서 저는 그냥 0시0분0초부터 h1:m1:s1 까지 만나는 횟수와 0시0분0초부터 h2:m2:s2까지 만나는 횟수를 구해서 빼주는 형식으로 구해줬습니다.

이경우 시작하는 초는 세면 안되므로 시작하는 초가 카운트에 세지는 0시0분0초와 12시0분0초만 예외처리해주면 조금 더 쉽게 해결할 수 있습니다.

작성중인 코드―solution.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function solution(h1, m1, s1, h2, m2, s2) {
    //0시0분0초 ~ h:m:s까지 겹치는 횟수
    const getCntFromMidNight = (h,m,s) => {
        const [hDegree,mDegree,sDegree] = [(h*30+m*0.5+s*0.5/60)%360,(m*6+s*0.1)%360,s*6]
        let ret = -1 //0시0분0초는 분에 한번이므로 -1로 시작
        // 마지막 분의 상태를 계산
        if(sDegree>=mDegree) ret +=1
        if(sDegree>=hDegree) ret +=1

        ret += (h*60+m)*2 //분당 2번씩 만난다고 계산
        ret -= h //59분 -> 0분일때는 분침과 만나지 않음
        if(h>=12) ret -= 2 // 11시59분59초 -> 12시인경우 분,초침과 만나지않고 12시에 2번이아닌 1번만 만나는걸로 처리
        return ret
    }

    //0시~주어진시간까지 횟수를 구한 이후 빼면 됨
    let ret = getCntFromMidNight(h2,m2,s2) - getCntFromMidNight(h1,m1,s1)
    if((h1===0||h1===12)&&m1===0&&s1===0) ret +=1 //0시와 12시인경우에만 예외적으로 1씩 더해줌
    return ret

}


  • 유원우

    최곱니다👍 설명 감사합니다~

    유원우―2024.01.23 10:21
  • 이민지

    천재이신가요?

    이민지―2024.04.29 15:30
1 개의 답변
나찬진

Gosu

답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.