티스토리 뷰

#include <string>
#include <vector>
#include <cmath>

using namespace std;

int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
    int answer = 0;

    int sTime = h1 * 3600 + m1 * 60 + s1;
    int eTime = h2 * 3600 + m2 * 60 + s2;

    if (sTime == 0 || sTime == 12 * 3600) answer++;

    while (sTime < eTime) {
        double hCur = fmod(sTime / 120.0, 360.0);
        double mCur = fmod(sTime / 10.0, 360.0);
        double sCur = fmod(sTime * 6.0, 360.0);

        double hNext = fmod((sTime + 1) / 120.0, 360.0);
        double mNext = fmod((sTime + 1) / 10.0, 360.0);
        double sNext = fmod((sTime + 1) * 6.0, 360.0);

        if (hNext == 0) hNext = 360;
        if (mNext == 0) mNext = 360;
        if (sNext == 0) sNext = 360;

        if (sCur < hCur && sNext >= hNext) answer++;
        if (sCur < mCur && sNext >= mNext) answer++;

        if (abs(sNext - mNext) < 1e-8 && abs(mNext - hNext) < 1e-8) answer--;

        sTime++;
    }

    return answer;
}

 

주어진 시, 분, 초 에 대해서 시작 시간과 끝 시간 값을 따로 곱하여 계산해준다.

만약 시각 시간이 0이거나, 43200인 경우는 00시 또는 12시에 해당하는 케이스이기에 카운팅을 해준다.

이후로는 시분초의 이동하는 각도에 따라 겹치는지 아닌지를 체크해준다.

 

현재 시분초에 대한 각도를 먼저 구해주자.

시침 
1시간에 30도 -> 1분에 0.5도 -> 1초에 1/120도

분침
1분에 6도 -> 1초에 1/10도

초침
1/10 * 60 = 6도

 

이제 1초를 증가시켜 변화한 다음 시분초 각도도 마찬가지로 구해준다.

이때 주의할 점은 실수를 다루기 때문에 %연산자가 아닌 fmod 함수를 이용하여 실수 나머지를 구해주었다.

추가로 주의할 것은 시분초 다음 값이 0이 되는 순간이다.

각도 0과 360은 같은 위치이지만, 0으로 두면 조건문에서 제대로 값을 체크 할 수가 없다.

따라서 0의 경우 360으로 바꿔준다.

 

이후에 위 값들을 토대로 겹침을 판별한다.

그리고 초침, 분침, 시침이 모두 겹칠 때는 알람을 1번만 울려야 하기에 중복되는 케이스를 찾아 감소시켜준다.

이를 1초씩 계속 증가시키며 eTime까지 반복한다.

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함