<문제>
<입력>
- 정수(h1, m1, s1, h2, m2, s2) - 알람이 울리는 횟수를 센 시간
- h1시 m1분 s1초 ~ h2시 m2분 s2초
<출력>
| h1 | m1 | s1 | h2 | m2 | s2 | result |
|---|
| 0 | 5 | 30 | 0 | 7 | 0 | 2 |
| 12 | 0 | 0 | 12 | 0 | 30 | 1 |
| 0 | 6 | 1 | 0 | 6 | 6 | 0 |
| 11 | 59 | 30 | 12 | 0 | 0 | 1 |
| 11 | 58 | 59 | 11 | 59 | 0 | 1 |
| 1 | 5 | 5 | 1 | 5 | 6 | 2 |
| 0 | 0 | 0 | 23 | 59 | 59 | 2852 |
<제한사항>
- 0 ≤
h1, h2 ≤ 23
- 0 ≤
m1, m2 ≤ 59
- 0 ≤
s1, s2 ≤ 59
h1시 m1분 s1초부터 h2시 m2분 s2초까지 알람이 울리는 횟수를 센다는 의미입니다.
h1시 m1분 s1초 < h2시 m2분 s2초
- 시간이 23시 59분 59초를 초과해서 0시 0분 0초로 돌아가는 경우는 주어지지 않습니다.
<풀이>
- 가장 먼저 각도로 푸는 걸 생각해보았는데 너무 복잡하고 예외가 많아 각도가 아니라 수학적사고로 풀려고 했다. 너무 어려워서 다른 분의 설명을 보고 구현했다.(맨 아래에 참조 적어둠)
- 모두 초로 변환해서 몇 번 겹치는 지 계산해야한다.
- 문제에 알려준 마지막 예시인 0시 0분 0초부터 23시 59분 59초까지 초침과 시침/분침이 겹치는 횟수가 2852번 인 것이 힌트이다.
- 1분에 초침은 1바퀴 도는데 그럼 1분에 분/시침과 2번 만나므로 1시간에 120번이며 24시간에 2880번이다. 하지만 그럼 28번의 차이가 발생한다.
- 사실 59분에서 정각으로 넘어갈 때는 초침과 분침이 만나지 않는다. 그러므로 24번은 만나지 않는 것이므로 (28-24)번의 경우만 더 찾으면 된다.
- 마찬가지로 0시 0분 0초와 12시 0분 0초로 넘어갈 때는 초침과 시침이 만나지 않는다. 그러므로 1번씩 더 빼준다.(4-2)
- 0시 0분 0초와 12시 0분 0초는 3개의 침 모두 동시에 만나므로 1번씩 더 빼준다. (2-2)
- 정해진 시간(초)동안 몇번 울렸는 지를 구해야한다.
- 이 풀이와 아래의 전체코드의 주석을 함께 보면 이해가 잘 될 것이다.
<전체코드>
class Solution {
public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
int answer = 0;
int bonus=0;
if(h1*3600 + m1*60 + s1==0 || h1*3600 + m1*60 + s1==43200)
bonus = 1;
return getCount(h2,m2,s2) - getCount(h1,m1,s1) + bonus;
}
public int getCount(int h1, int m1, int s1) {
int total = h1*3600 + m1*60 + s1;
int m_alram = (total*59)/3600;
int h_alram = (total*719)/43200;
int count = m_alram + h_alram;
if(h1>=12) {
count--;
}
return count;
}
}
<참조>
https://taehoung0102.tistory.com/321