[프로그래머스] 아날로그 시계 - 250135(Java)

개발하는 파랑이·2024년 3월 16일

프로그래머스

목록 보기
4/5

<문제>

<입력>

  • 정수(h1, m1, s1, h2, m2, s2) - 알람이 울리는 횟수를 센 시간
    • h1시 m1분 s1초 ~ h2시 m2분 s2초

<출력>

  • 알람이 울리는 횟수 return
h1m1s1h2m2s2result
05300702
1200120301
0610660
11593012001
115859115901
1551562
0002359592852

<제한사항>

  • 0 ≤ h1h2 ≤ 23
  • 0 ≤ m1m2 ≤ 59
  • 0 ≤ s1s2 ≤ 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) //오전 12시 or 오후 12시
            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; //분침과 초침간 알람(초침이 먼저 움직이기 때문에 마지막 한번은 필요없음 그래서 59번)
        int h_alram = (total*719)/43200; //시침과 초침간 알람(분침과 마찬가지로 마지막 한번은 필요없음)
        int count = m_alram + h_alram;
        if(h1>=12) { //알람을 24시간 기준이 아닌 12시간 기준으로 했기 때문에 한번 중복(세 침 동시에)이 생기므로 1빼줘야함
            count--;
        }
        return count;
    }
}

<참조>

https://taehoung0102.tistory.com/321

profile
이것저것 개발자

0개의 댓글