[BaekJoon] 2884번 - 알람 시계 (java)

1. 문제

👉 문제 바로가기

- 조건

시간 제한 메모리 제한
1초 128MB


- 문제

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

상근이는 모든 방법을 동원해보았지만, 조금만 더 자려는 마음은 그 어떤 것도 없앨 수가 없었다.

이런 상근이를 불쌍하게 보던 창영이는 자신이 사용하는 방법을 추천해 주었다.

바로 "45분 일찍 알람 설정하기"이다.

이 방법은 단순하다. 원래 설정되어 있는 알람을 45분 앞서는 시간으로 바꾸는 것이다. 어차피 알람 소리를 들으면, 알람을 끄고 조금 더 잘 것이기 때문이다. 이 방법을 사용하면, 매일 아침 더 잤다는 기분을 느낄 수 있고, 학교도 지각하지 않게 된다.

현재 상근이가 설정한 알람 시각이 주어졌을 때, 창영이의 방법을 사용한다면, 이를 언제로 고쳐야 하는지 구하는 프로그램을 작성하시오



- 입력

첫째 줄에 두 정수 H와 M이 주어진다. (0 ≤ H ≤ 23, 0 ≤ M ≤ 59) 그리고 이것은 현재 상근이가 설정한 알람 시간 H시 M분을 의미한다.

입력 시간은 24시간 표현을 사용한다. 24시간 표현에서 하루의 시작은 0:0(자정)이고, 끝은 23:59(다음날 자정 1분 전)이다. 시간을 나타낼 때, 불필요한 0은 사용하지 않는다.

- 출력

첫째 줄에 상근이가 창영이의 방법을 사용할 때, 설정해야 하는 알람 시간을 출력한다. (입력과 같은 형태로 출력하면 된다.)

- 예제

  입력      출력  
10 10 9 25
0 30 23 45
23 40 22 55





2. 풀이

조건에 맞는 알람 시간을 출력하기 위해 조건문 if를 사용한다.

또한 if 대신 삼항 연산자 를 사용해서 조건문을 한 줄로 줄이는 방법도 설명한다.



2가지 입력방법을 사용해서 결과를 출력한다.

  1. Scanner 클래스 - if 조건문 사용
  2. BufferedReader 클래스
      ① StringTokenizer 클래스 - 삼항 연산자 사용
      ② split() 메서드



- 1. Scanner 클래스 사용

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        
        int h = sc.nextInt();
        int m = sc.nextInt();
        
        if(m<45) {
            h--;
            m = 60+(m-45);
            
            if(h<0) h = 23; 
            
            System.out.println(h +" "+ m);
        }
        else System.out.println(h +" "+ (m-45));
        
    }
}

위와같이 객체를 생성할 때, Scanner(System.in) 에서 System.in 은 입력한 값을 Byte 단위로 읽는 것을 뜻한다.

int형 데이터를 입력받기 위해 nextInt() 메서드를 사용한다.



[여기서 잠깐!]

Scanner에 대해 더 자세히 알고싶다면 여기 를 클릭하세요





- 2. BufferedReader 클래스 사용

BufferedReader는 readLine() 메서드를 사용해 한 행을 전부 읽는다.
이를 공백단위로 분리해야 하는데, 두가지 분리 방법으로 문제를 풀어보자.



     ① StringTokenizer 클래스를 사용하여 분리해주는 방법
     ② split() 을 사용하는 방법



여기서 삼항 연산자도 함께 사용해보자.

변수 = (조건문) ? (true 인 경우 연산) : (false 인 경우 연산)

조건이 2개 이상일 경우, 두번째 연산 위치에 또 다른 삼항 연산자를 쓸 수 있다.



① StringTokenizer 클래스를 이용

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        int h = Integer.parseInt(st.nextToken()); // 설정한 알람 시
        int m = Integer.parseInt(st.nextToken()); // 설정한 알람 분
       
        System.out.println(m<45 ? h-1<0 ? 23+" "+(60+(m-45)) : h-1+" "+(60+(m-45)) : h+" "+(m-45));
    }
}

readLine()은 한 줄을 통째로 읽어 String으로 반환하기 때문에, StringTokenizer 클래스의 nextToken()를 이용해 공백으로 구분된 입력값들을 순서대로 가져온다.

Integer.parseInt()을 사용해 String형을 int형으로 변환시켜준다.



[여기서 잠깐!]

BufferedReader 클래스에 대해 더 알아보고 싶으면 여기를 클릭하면 된다.





② split() 을 사용

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        String[] arr = br.readLine().split(" ");

        int h = Integer.parseInt(arr[0]); // 설정한 알람 시
        int m = Integer.parseInt(arr[1]); // 설정한 알람 분
       
        System.out.println(m<45 ? h-1<0 ? 23+" "+(60+(m-45)) : h-1+" "+(60+(m-45)) : h+" "+(m-45));
    }
}

readLine()을 통해 한 줄로 받은 String 데이터를 split(" ") 메서드를 사용해 공백 단위로 나눈 뒤 배열에 저장한다.

위의 삼항 연산자의 조건문이 true인 경우, 만약 알람을 설정한 시각이 0시일 경우 다시 한번 삼항 연산자를 중첩해서 사용한다.





3. Scanner VS BufferedReader 성능 비교

image

입력의 경우 확실히 Scanner 보다는 BufferedReader 가 빠른 것을 볼 수 있다.





관련 페이지





Categories:

Updated:

Leave a comment