IT/JavaScript

[백준/JAVA] 2884 알람시계

Buang 2023. 2. 19. 18:44
반응형

1. 문제

 

 

2884번: 알람 시계

상근이는 매일 아침 알람을 듣고 일어난다. 알람을 듣고 바로 일어나면 다행이겠지만, 항상 조금만 더 자려는 마음 때문에 매일 학교를 지각하고 있다. 상근이는 모든 방법을 동원해보았지만,

www.acmicpc.net


2. 풀이

 

사용자가 평소에 7시에 기상이라

7시로 알람을 설정해 놨다면

7시보다 45분 더 빠른 6시 15분이 출력되도록 해야 한다.

 

즉 사용자가 입력한 값이 7 0 (7시)일 때

출력값은 6 15 가(6시 15분) 나오도록 해야 한다.

 

 

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
    
		Scanner scan = new Scanner(System.in);
		
		int H = scan.nextInt(); // 시간
		int M = scan.nextInt(); // 분
		
		scan.close();

 

일단 시간과 분을 입력할 수 있도록 scnnaer를 사용해

두 수를 입력받을 수 있도록 했다.

 

 

그리고 입력한 시간에서 45분을 제외하려면

몇 가지 조건을 지켜야 한다.

 

 

1) 만약 분이 45 이하고, 시간이 1 이상이라면?

 

 

사용자가 7시에 기상이라 7시를 의미하는 7 0을 입력했을 경우

7시보다 45분 빠른 6 15가 출력되도록 해야한다.

 

이를 위해선 시간을 나타내는 7에서

1을 빼줘서 6이 나오도록 해야한다.

 

분의 경우 60 - (45 - 분) 식을 통해 분을 구해주면 답이 나온다.

여기선 분이 0이라 60 - (45 - 0)은 15분이 나온다. 

 

시간에서 1을 빼주고

분은 60 - (45 - 분) 공식을 대입해주면

최종적으로 7시에서 45분 더 이른

6시 15분이 위의 식을 통해 나올 수 있다.

 

if(H > 0 && M < 45) { //입력된  시간이 1 이상이고, 분이 45분 이하면
    H--;		// 시간 -1 감소
    M= 60 - (45 - M); 	// 분은 45분 감소
    System.out.println(H + " " + M);
}

 

이를 코드로 표현하면 위와 같다.

만약 분이 45분 이하라면 시간을 1 줄이고,

분은 60 - (45 - M) 식을 적용해서 구하면 된다.

 

 

1-1) 분이 45분 이하면서 시간이 0 일 때

 

위에선 분이 45분 이하임과 동시에 시간이 0 이상일 때였다.

그런데 분이 45분 이하인데 시간이 0인 경우

이럴 땐 시간을 1 줄일 수 없다.

0에서 -1을 하면 -1이 나오는데 시간에서 -1시간은 없으니 말이다.

 

시간이 0인 경우는 23으로 만들어줘야 한다.

 

23시> 0시> 1시 > 2시 ...

 

위에는 시간 순서다.

2시의 이전 시간은 1시다.

0시의 이전 시간은 23시다.

 

0시에서 45분을 제외하면

0시 이전인 23시이기 때문에

입력된 시간이 0시 이면 0시 이전인 23으로 만들어 줘야 한다.

 

예시로 사용자가 0 30 분을 입력했을 경우

0시 30분의 45분 전인

23 45가 출력되도록 하면 된다.

 

이를 코드로 표현하면 아래와 같다.

 

else if (H == 0 && M < 45) { //입력된 시간이 0이고, 45분 이하라면
    H = 23;
    M= 60 - (45 - M); 	// 분은 45분 감소
    System.out.println(H + " " + M);
    }

 

 

 

2) 만약 분이 45 이상이라면?

 

사용자가 7시 50분에 기상이라 

7 50을 입력했다고 하자.

 

7시 50분에서 45분을 제외하면

7시 5분이니 사용자가 7 50을 입력했다면

7 5가 출력되도록 하면 된다.

 

7시 50분처럼  분이 45 이상일 경우

시간 부분(7)은 그대로 둬도 되며

분(50)부분만 45로 빼주면 된다.

 

식으로 표현하면 분 - 45 가 된다.

여기선 50 - 45 = 5분가 된다.

 

시간은 그대로 두고 분 부분만 45로 빼줬기에

사용자가 7 50을 입력하면 7 5가 출력될 것이다.

 

else { // 	분이 45분 이상인 경우
    System.out.println(H + " " + (M - 45));
}

 

설명한 부분을 코드로 표현하면 위와같다.

 

 

3. 최종코드

 

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
    
		Scanner scan = new Scanner(System.in);
		
		int H = scan.nextInt(); // 시간
		int M = scan.nextInt(); // 분
		
		scan.close();
		
		if(H > 0 && M < 45) { //입력된  시간이 1 이상이고, 분이 45분 이하면
			H--;		// 시간 -1 감소
			M= 60 - (45 - M); 	// 분은 45분 감소
			System.out.println(H + " " + M);
		}
		else if (H == 0 && M < 45) { //입력된 시간이 0이고, 45분 이하라면
			H = 23;
			M= 60 - (45 - M); 	// 분은 45분 감소
			System.out.println(H + " " + M);
			}
		else { // 	분이 45분 이상인 경우
			System.out.println(H + " " + (M - 45));
		}
	}
}

 

 

위의 코드를 보면 중복되는 부분이 보인다.

System.out.println(H + " " + M);이 2개 있고,

M = 60 - (45 -M); 도 2개 있다.

 

리팩토링 해보자!

 

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
    
		Scanner scan = new Scanner(System.in);
		
		int H = scan.nextInt(); // 시간
		int M = scan.nextInt(); // 분
		
		scan.close();
		
		if(M < 45) { //입력된  시간이 1 이상이고, 분이 45분 이하면
			H--;		// 시간 -1 감소
			M= 60 - (45 - M); 	// 분은 45분 감소
			
			if(H < 0) {//입력된 (분이 45분 이하고), 시간이 0보다 작다면
				H = 23; //시간을 0에서 23으로 바꾸기 
			}
			System.out.println(H + " " + M);
		}
		else { // 	분이 45분 이상인 경우
			System.out.println(H + " " + (M - 45));
		}

	}
}

 

리팩토링 했는 데 여전히 27줄인 건 무슨 일일까?

뭐 그건 됐고!

 

리팩토링 하면서 이해가 안 갔던 게

17번째 줄에 있는 if (H < 0) 부분이었다.

시간이 0인지 판별하면 되는 거니까

if ( H <= 0) 혹은 if ( H == 0)도 될 텐데

이 두 개를 넣었을 땐 오답이 뜨고

if (H < 0)으로 했을 때만 정답인지 이해가 가지 않았다.

 

H--;를 작성한 걸 잊어버린 게 화근이었다.

14번째 줄을 보면 H--;를 작성해서 

분이 45분 이하일 경우 무조건 시간 부분은 1을 빼주기로 했었다.

 

즉 0이 입력된다면 -1이 되는 것이다.

그러니 if (H <=0)이나 if(H == 0)은 넣어선 안된다.

 

현재 0시는 H--;에 의해 -1로 바뀌었기에

if (H < 0)을 넣어줘야 하는 게 맞다.

반응형