주어진 시간 시작시간 ~ 끝시간까지 시계가 움직일 때 초침이 시침/분침과 겹치는 횟수를 구해라.
00:00:00, 12:00:00은 2회가 아닌 1회로 처리한다.
ex)
h1, m1, s1 = 0, 5, 30
h2, m2, s2 = 0, 7, 0
00:05:30 ~ 00:07:00 동안 초침은 총 2회 시침/분침과 겹친다.
첫번째 00:06:0.501 (초침 & 시침)
두번째 00:06:6.102 (초침 & 분침)
처음에는 테스트 케이스에서 겹치는 정확한 시간을 알려주는 것을 보고
어떻게 정확한 시간을 구하지라는 틀에 갇혀서 풀지 못하고 있었다.
그러다가 1초마다 초침이 시침/분침을 지났는지만 검사하면 되지않을까? 라는 생각을 했다.
문제를 풀기위해 생각한 과정은 다음과 같다.
1. 초마다 검사를 해줘야하니 총 걸린시간을 초단위로 바꾸자.
2. 시침, 분침, 초침의 초당 움직이는 각도를 구하자.
자잘한 설명은 코드 주석으로 하겠다.
def solution(h1, m1, s1, h2, m2, s2):
answer = 0
# 시작시간과 끝시간을 초단위로 변환
startTime = h1 * 3600 + m1 * 60 + s1
endTime = h2 * 3600 + m2 * 60 + s2
# next기준으로 계산할거니 포함되지 않는 시작시간 00시, 12시 미리 카운팅
if startTime == 0 * 3600 or startTime == 12 * 3600:
answer += 1
while startTime < endTime:
# 시침 1시간 = 30도 -> 1초에 30/3600도 즉, 1/120도 이동
# 분침 1분 = 6도 -> 1초에 6/60도 즉, 1/10도 이동
# 초침 1초 = 6도 -> 1초에 6도 이동
hCurAngle = startTime / 120 % 360
mCurAngle = startTime / 10 % 360
sCurAngle = startTime * 6 % 360
# 다음 위치가 360도가 아닌 0도로 계산되어 카운팅에 포함되지 않는 경우 방지
# 이동했을 때 지나쳤거나 같아졌는지를 비교하는 것이므로 현재위치는 해줄 필요없음
hNextAngle = 360 if (startTime + 1) / 120 % 360 == 0 else (startTime + 1) / 120 % 360
mNextAngle = 360 if (startTime + 1) / 10 % 360 == 0 else (startTime + 1) / 10 % 360
sNextAngle = 360 if (startTime + 1) * 6 % 360 == 0 else (startTime + 1) * 6 % 360
if sCurAngle < hCurAngle and sNextAngle >= hNextAngle:
answer += 1
if sCurAngle < mCurAngle and sNextAngle >= mNextAngle:
answer += 1
# 시침/분침과 동시에 겹쳤을 때 중복카운팅 제외
if sNextAngle == hNextAngle and hNextAngle == mNextAngle:
answer -= 1
startTime += 1
return answer