세용용용용 2024. 8. 23. 15:19

시침, 분침, 초침이 있는 아날로그시계가 있습니다. 시계의 시침은 12시간마다, 분침은 60분마다, 초침은 60초마다 시계를 한 바퀴 돕니다. 따라서 시침, 분침, 초침이 움직이는 속도는 일정하며 각각 다릅니다. 이 시계에는 초침이 시침/분침과 겹칠 때마다 알람이 울리는 기능이 있습니다. 당신은 특정 시간 동안 알람이 울린 횟수를 알고 싶습니다.

다음은 0시 5분 30초부터 0시 7분 0초까지 알람이 울린 횟수를 세는 예시입니다.

  • 가장 짧은 바늘이 시침, 중간 길이인 바늘이 분침, 가장 긴 바늘이 초침입니다.
  • 알람이 울리는 횟수를 세기 시작한 시각은 0시 5분 30초입니다.
  • 이후 0시 6분 0초까지 초침과 시침/분침이 겹치는 일은 없습니다.

  • 약 0시 6분 0.501초에 초침과 시침이 겹칩니다. 이때 알람이 한 번 울립니다.
  • 이후 0시 6분 6초까지 초침과 시침/분침이 겹치는 일은 없습니다.

  • 약 0시 6분 6.102초에 초침과 분침이 겹칩니다. 이때 알람이 한 번 울립니다.
  • 이후 0시 7분 0초까지 초침과 시침/분침이 겹치는 일은 없습니다.

0시 5분 30초부터 0시 7분 0초까지는 알람이 두 번 울립니다. 이후 약 0시 7분 0.584초에 초침과 시침이 겹쳐서 울리는 세 번째 알람은 횟수에 포함되지 않습니다.

다음은 12시 0분 0초부터 12시 0분 30초까지 알람이 울린 횟수를 세는 예시입니다.

  • 알람이 울리는 횟수를 세기 시작한 시각은 12시 0분 0초입니다.
  • 초침과 시침, 분침이 겹칩니다. 이때 알람이 한 번 울립니다. 이와 같이 0시 정각, 12시 정각에 초침과 시침, 분침이 모두 겹칠 때는 알람이 한 번만 울립니다.

  • 이후 12시 0분 30초까지 초침과 시침/분침이 겹치는 일은 없습니다.

12시 0분 0초부터 12시 0분 30초까지는 알람이 한 번 울립니다.

알람이 울리는 횟수를 센 시간을 나타내는 정수 h1, m1, s1, h2, m2, s2가 매개변수로 주어집니다. 이때, 알람이 울리는 횟수를 return 하도록 solution 함수를 완성해주세요.


제한사항

  • 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초로 돌아가는 경우는 주어지지 않습니다.

입출력 예

h1m1s1h2m2s2result

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

 

코딩테스트 연습 - [PCCP 기출문제] 3번 / 아날로그 시계 | 프로그래머스 스쿨 (programmers.co.kr)

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

나의 풀이

# 2024-08-22
def solution(h1, m1, s1, h2, m2, s2):
    answer = 0
    start_second = (h1*60*60)+(m1*60)+s1
    end_second = (h2*60*60)+(m2*60)+s2
    
    # 시작 전 이미 조건을 만족한 경우 (0시, 12시)
    if (start_second == 0) or (start_second == 43200):
        answer+=1
        
    while start_second < end_second:
        # 시계는 한바퀴 돌기에 각도로 접근해보자 (1바퀴 >> 360도)
        # 시는 1초당 (1/120)도 이동
        # 분은 1초당 (1/10)도 이동
        # 초는 1초당 6도 이동

        # 시, 분, 초의 현재 위치
        hour, minute, second = (start_second/120)%360, (start_second/10)%360, (start_second*6)%360
        
        
        # 다음 위치 ( 0인 경우 360도 여야됨 카운트를 위함 )
        if ((start_second+1)/120)%360 == 0:
            hour_next = 360
        else:
            hour_next = ((start_second+1)/120)%360
        
        if ((start_second+1)/10)%360 == 0:
            minute_next = 360
        else:
            minute_next = ((start_second+1)/10)%360
        
        if ((start_second+1)*6)%360 == 0:
            second_next = 360
        else:
            second_next = ((start_second+1)*6)%360
        
        # 1초 동안 초가 시,분을 지나쳤으면 카운트
        # 시, 분이 같으면 동시에 지나쳤기에 알람은 한번 울리므로 -1 해줘야됨
        if second < hour and second_next >= hour_next:
            answer+=1
        if second < minute and second_next >= minute_next:
            answer+=1
        if second_next==hour_next and second_next==minute_next:
            answer-=1
        start_second+=1

    return answer

 

시간 복잡도

while start_second < end_second : 끝날떄까지 순회하므로 (  선형 시간복잡도 )
    내부 시간 구하는 연산이나 분기는 >> 상수시간
즉, 해당 알고리즘 최종 시간 복잡도는 선형 시간복잡도 ( O(n) )