728x90

 

문제 : 2525번 : 오븐 시계

2525번: 오븐 시계 (acmicpc.net)

 

2525번: 오븐 시계

첫째 줄에 종료되는 시각의 시와 분을 공백을 사이에 두고 출력한다. (단, 시는 0부터 23까지의 정수, 분은 0부터 59까지의 정수이다. 디지털 시계는 23시 59분에서 1분이 지나면 0시 0분이 된다.)

www.acmicpc.net

 

 

문제 조건

  • 시작 시간과 조리 시간 주어졌을 때, 요리 끝나는 시간 구하기
  • 첫째줄 : 현재 시각
  • 둘째줄 : 필요 시간
  • 시간의 입출력 : 정수, 시와 분 사이에 공백으로 표현할 것
  • 24시간제 : 23시 넘어가면 0시로
  • 두 줄을 받는데 한 줄에 공백을 처리하면서 받을 수 있어야함

 

풀이 과정

brain Storming

필요 시간이 60분이 넘어가면, 끝나는 시간(hour)에 60분당 +1(최대 1000분이므로 16시간까지 +가능)
 시작 시간의 분과 필요시간의 분을 더하여 끝나는 시간의 시(hour)를 도출해야함
 BufferedReader 두줄이상 받기 : 공백 마다 기준 하나마다 st하나씩 받고 다음 줄은 br로 또 받으면 됨

min + need
   - min 59초과시, hour +1
   - cookTime > 60이면, +1

14 30 + 20 = 14 50
14 30 + 30 = 15 00 -> hour에 +1 되어야함

요리 시간 60이 넘어가면 +1해야함

 60분 이상이면 hour에 +1 해줘야하는데, 2,3시간 넘어갈 경우 각각의 경우의 수를 고려해야함
 1000분 제한이라 switch로 일일히 각 시간을 나눠서 할 수 있지만 너무 비효율적임. 다른 방법이 뭐가 있을까?
 분 단위 계산으로 min에 cookTime을 더하고, 총 min을 60으로 나눠서 hour 더하면 될 듯...?

 

 

해설

전체를 분으로 바뀌서 후에 60을 나누거나 나머지로 시, 분을 각각 구하는 방식
시를 분으로 변환(변수 min)
여기에 요리시간(분)을 더함
이 상태에서 60으로 나눈 나머지가 시(hour)가 되는데, 23시를 넘어가는 경우를 생각해서 24로 나누고 난 나머지를 hour로 사용
또한 분(변수 minute)도 60으로 나눈 나머지는 60이하만 나오기 때문에 자연스레 분으로 만들어진다 

입력값 17 40과 80을 예로 계산해보면 아래의 주석과 같다

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
int C = Integer.parseInt(br.readLine());

int min = 60 * A + B;  // 시 -> 분                // 60 * 17 + 40 = 1060 min
min += C;              // 전체 분 + 요리시간 분의 합 // 1060 + 80 = 1140min

int hour = (min / 60) % 24; // 23시를 넘은 0시를 위한 처리           // (1140 / 60) % 24 = 19
int minute = min % 60;      // 60분 넘어가면 나머지만 구하면 분이 나옴 // (1140 % 60) = 0

System.out.println(hour + " " + minute);

 

정답

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 A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
 
        int C = Integer.parseInt(br.readLine());
 
        int min = 60 * A + B;   // 시 -> 분
        min += C;
 
        int hour = (min / 60) % 24;
        int minute = min % 60;
 
        System.out.println(hour + " " + minute);
 
    }
}

 

 

728x90
반응형
728x90

 

  1. 2대 스캐너
  2. 단일 스캐너
  3. BufferedReader class

 

1. 스캐너 2개 사용

Scanner + while(sc.hasNextLine()) + [] sc.nextLine().split(”\\s”)

 

2. 단일 스캐너

ArrayList + while(sc.hasNext()) + add(sc.next())

 

3.BufferedReader

BufferedReader + while( 변수.readline() != null )+ [] 변수.split(”\\s”)

스캐너는 try catch가 자동으로 되고 BufferedReader는 익셉션을 수동으로 잡아줘야해서 try catch 필수

 

참고자료

https://www.techiedelight.com/ko/read-multi-line-input-console-java/

728x90
반응형
728x90

 

입력, 출력값 맞게 넣었고 같은 값이고 로직도 맞는 것 같은데 틀리다고 나온다면...?

왜 틀렸는지 몰라서 난감할 것이다

 

이럴 때 한가지 해볼만한 추천 방법이 있다

구글링해서 해당 문제를 푼 다른 분들의 코드를 보고 이해한 후,

코드 로직에서 비슷한 부분이 꽤 있을 것이다. 

해당 부분을 하나씩 바꿔서 정답 처리를 확인하면서 로직이나 코드 맞는지 틀린지 확인 가능해지면서

뭐가 틀리고 맞는지 확인이 가능하다.

 

 

예를들면,

내가 풀어낸 처음 코드는 아래와 같았는데

로직을 여러번 검산해봐도 맞는데 왜 아니라고 하는건지 입출력 값 다 확인해봐도 이해가지 않았다

if((min-45) < 0 ){
    hour = hour-1;
    min = min - 45 + 60;
    if(hour < 0){
       hour = hour + 24;
    }
}
System.out.println(hour+" "+min);

 

 

다른 사람들의 코드 방식 찾아보니 아래와 같았는데

h=23나 M<45 같은 코드들이 좀 달라서

혹시 내가 놓친 다른 경우의 수가 있나 한 줄씩 대입해서 보니 다 정답 처리 되는 것이다

모든 라인을 하나 씩 해보니 그제서야 로직은 틀린게 없고

else로 첫 if문 조건이 아닌 경우의 수를 주어야하는 걸 깜빡한 것을 발견할 수 있었다

if(M < 45) {
    H--;
    M = 60 - (45 - M);
    if(H < 0) {
        H = 23;
    }
    System.out.println(H + " " + M);
}
else {
    System.out.println(H + " " + (M - 45));
}

 

 

 

 

728x90
반응형
728x90

문제 : 백준 2884번 : 알람 시계

2884번: 알람 시계 (acmicpc.net)

 

2884번: 알람 시계

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

www.acmicpc.net

 

 

풀이 과정

문제 조건

  • 입력 첫 줄 : int 2ea
    • h : hour    0~23
    • m : minute  0~59
  • 시간표시 : 24시간 형태
    • 불필요한 0표시 x
  • 첫째 줄에 상근이가 창영이의 방법을 사용할 때, 설정해야 하는 알람 시간을 출력한다

brain Storming
입력된 설정 시간보다 시간이 빨라야함(값이 작아야함)
-45 한다고하면 hour가 -1되는 경우와 -1시가 되는 경우가 고려되어야함

 

 

해설

1. 분(min)이 -1이하가 되는 경우
  - 0분에서 -되면 59부터 시작해야함 ex)2시30분-45분=1시45분가 되게 해야함
+60하면 된다
  30-45=45 // 30-45=-15+60 = 45
  20-45=35 // 20-45=-25+60 = 35
  10-45=25 // 10-45=-35+60 = 25
  00-45=15 // 00-45=-45+60 = 15
2. 시(hour)에 -1해야되는 경우 고려
  - if로 min을 -45해서 h의값이 0이하일 때 -1이면, 23으로 가게해야함
  0:30-45=23:45 // 

  h값 범위 0~23
  0-1 = -1 + 24 = 23
  1-1 = 0 + 24 = 24 // 24시는 0시로 표시해야함
  2-1 = 1 + 24 = 25 // 여기부터는 실질적으로 1시이므로 +24 할 필요 없음
  3-1 = 2 + 24 = 26
  ...
  23-1 = 22 + 24 = 46

  hour -1해서 값이 -인 경우에만 +24하거나 그냥 hour를 if조건줘서 23으로 지정하면 됨

 

정답

import java.io.InputStreamReader;
import java.io.BufferedReader;
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 hour = 0;
        int min = 0;

        while(st.hasMoreTokens()){
            hour = Integer.parseInt(st.nextToken());
            min = Integer.parseInt(st.nextToken());
        }

        if((min-45) < 0 ){
            hour = hour-1;
            min = min - 45 + 60;
            if(hour < 0){
               hour = hour + 24;
            }
			System.out.println(hour + " " + min);
		}
		else {
			System.out.println(hour + " " + (min - 45));
		}


    }
}

 

다른 코딩 방식

//        if(min < 45){
//        if((min-45) < 0 ){
//            hour = hour-1;
//            hour--;
//            min = min - 45 + 60;
//            min = 60 - (45 - min);
//            if(hour < 0){
//                hour = hour + 24;
//                hour = 23;
//            }
//        }

 

 

 

728x90
반응형
728x90

 

문제 : 14681번: 사분면 고르기 (acmicpc.net)

 

14681번: 사분면 고르기

점 (x, y)의 사분면 번호(1, 2, 3, 4 중 하나)를 출력한다.

www.acmicpc.net

 

 

※ 해설과 정답은 아래

 

풀이과정

찻줄 정수x 다음줄 정수y주어진다고 해서 StringTokenizer로 받으면 오답처리 될지도 모름
오답 처리시, BufferedReader 2개로 받아보자

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(),",");

int x = 0;
int y = 0;
while(st.hasMoreTokens()){
    x = Integer.parseInt(st.nextToken());
    y = Integer.parseInt(st.nextToken());
}

System.out.println(x);
System.out.println(y);

if( x > 0 && y > 0){
    System.out.print(1);
}else if(x < 0 && y > 0){
    System.out.print(2);
}else if( x < 0 && y < 0){
    System.out.print(3);
}else if(x > 0 && y < 0){
    System.out.print(4);
}else{
    System.out.print("잘못 입력 되어있습니다");
}

인텔리제이에서 돌리면 작동 잘하는데 백준에서 런타임 에러 (NoSuchElement) 발생

아마도 다른 입력 경우의수가 잘못된게 아닌가 싶다

 

BufferedReader 2개 받아 시도

BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));

int x = Integer.parseInt(br1.readLine());
int y = Integer.parseInt(br2.readLine());

if( x > 0 && y > 0){
    System.out.print(1);
}else if(x < 0 && y > 0){
    System.out.print(2);
}else if( x < 0 && y < 0){
    System.out.print(3);
}else if(x > 0 && y < 0){
    System.out.print(4);
}else{
    System.out.print("잘못 입력 되어있습니다");
}

이번에는 런타임 에러(NumberFormat) 발생

런타임에러 : 배열의 크기를 잘못지정하거나 함수가 끝나지 않을 시 발생

 

라고 하는데 배열도 없고 배열로 반환하는 메소드도 없고, 함수도 다 잘 마무리 되었다

뭐가 문제일까?

 

0 입력 방지 + else의 에러메시지가 str이므로 제거 해보자

x,y쪽 br 받는 부분만 for 돌려서 0 안받는 방법?

if( x > 0 && y > 0 && x!=0 && y!=0){
    System.out.print(1);
}else if(x < 0 && y > 0 && x!=0 && y!=0){
    System.out.print(2);
}else if( x < 0 && y < 0 && x!=0 && y!=0){
    System.out.print(3);
}else if(x > 0 && y < 0 && x!=0 && y!=0){
    System.out.print(4);
}else{
    System.out.print("잘못 입력 되어있습니다");
}
int x = 0;
int y = 0;
for(int i=1; i <=2; i++) {
    if(x!=0 && y!=0) {
       x = Integer.parseInt(br1.readLine());
       y = Integer.parseInt(br2.readLine());
    }
}

위의 둘을 적용해도 런타임 에러(NumberFormat) 발생

 

뭐가 문제일까...?

첫 줄에는 정수 x가 주어진다. (−1000 ≤ x ≤ 1000; x ≠ 0) 다음 줄에는 정수 y가 주어진다. (−1000 ≤ y ≤ 1000; y ≠ 0)
-> 백준에서 이런 조건이 주어지면 테스트 시, 해당 수의 범위만 테스트한다는 의미
   즉, 0입력을 코드에서 고려할 필요없고, 다른게 문제라는 의미

 

 

 

BufferedReader 2개로 각각 x,y로 받았을 때 런타임에러(NumberFormat) 발생한 이유


백준에서는 파일 형식으로 받는데(IDE에서의 작동방식과 다르다는 의미)
스트림으로 데이터를 받을 때, BufferedReader 2개로 각각 받으면 IDE랑 다르게
파일형식이라 첫줄에 br1이 값을 받아 x로 넘기고 br1 값은 지워지고 br2 받을 때 둘째줄로 넘어가는게 아닌
첫줄에서 시작하고 또한 공백값을 받기에 br2가 공백을 받아 NumberFormat이 발생한 것

br을 두개에서 하나로 줄여서 문제 해결

 


 

 

해설

  • 양수 구분 : 0초과  ex) x > 0
  • 음수 구분 : 0미만  ex) x < 0

BufferedReader생성하여 값을 입력 받고

br.readLine()으로 x,y 각각 값을 입력 받는다

AND(&&)로 x,y의 각각 조건인 양수,음수들을 if문 조건에 넣고

x,y가 각각 양수면 1분면 식으로 조건을 줘도 뽑아내면 된다

 

이때 주의할 점은

첫 줄에는 정수 x가 주어진다. (−1000 ≤ x ≤ 1000; x ≠ 0) 다음 줄에는 정수 y가 주어진다. (−1000 ≤ y ≤ 1000; y ≠ 0)

라는 조건이 백준에서 주어지면 코드에서는 저 범위와 0에 대해서는 신경 안써도 된다. 즉, 테스트할 때 해당 숫자의 조건만 테스트를 돌리기 때문에 0이 들어오는 경우의 수도 신경 안써도 됐었음

 

 

정답

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
    public static void main(String[] args) throws IOException {

       BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));

        int x = Integer.parseInt(br1.readLine());
        int y = Integer.parseInt(br1.readLine());

        if( x > 0 && y > 0){
            System.out.print(1);
        }else if(x < 0 && y > 0){
            System.out.print(2);
        }else if( x < 0 && y < 0){
            System.out.print(3);
        }else if(x > 0 && y < 0){
            System.out.print(4);
        }else{
            System.out.print("잘못 입력 되어있습니다");
        }

    }
}

 

 

 

 

728x90
반응형
728x90

 

문제 : 2753번: 윤년 (acmicpc.net)

 

2753번: 윤년

연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오. 윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다. 예를 들어, 2012년은 4의 배수이면서

www.acmicpc.net

 

 

// brain Storming
// 조건
// 윤년 == 4의배수인 연도 중 100의 배수가 아닌 연도 or 400의 배수인 연도
// 4의 배수이면서 100의 배수가 아님 : (year%4 == 0) and !(year%100 == 0)

풀이

4배수인지를 구하는 방법은 num%4를 해서 나머지가 0이 나오면 해당 배수이고 다른 수가 나오면 4의 배수가 아니다

그렇기에 year%4 == 0이면 이라는 조건과 동시에 100의 배수가 아니어야 하기에 &&(and)조건으로 100의 배수가 아닌 조건 !(year%100 == 0)을 주어서 윤년을 구했고

마찬가지로 400의 배수도 year%400 == 0으로 구했다

이외의 나머지 else는 전부 평년

 

 

정답

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

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int year = Integer.parseInt(br.readLine());

        if(((year%4 == 0) && !(year%100 == 0))){
            System.out.println("1");
        }else if(year%400 == 0){
            System.out.println("1");
        }else{
            System.out.println("0");
        }
    }
}

 

 

728x90
반응형
728x90

 

문제 : 3003번: 킹, 퀸, 룩, 비숍, 나이트, 폰 (acmicpc.net)

 

3003번: 킹, 퀸, 룩, 비숍, 나이트, 폰

첫째 줄에 동혁이가 찾은 흰색 킹, 퀸, 룩, 비숍, 나이트, 폰의 개수가 주어진다. 이 값은 0보다 크거나 같고 10보다 작거나 같은 정수이다.

www.acmicpc.net

 

 

큰 틀에서의 로직은

갖춰야할 장기말의 수 - 입력 받은 수

           A                      -             B

 

즉 A-B를 각각 배열로 만들어서 for문을 돌려 인덱스번호 별로 호출하여 각 번호를 빼주는 것이다

answer = A[i] - B[i]

 

갖춰야할 장기말의 수 : 변수명 horse

int[] horse = {1,1,2,2,2,8};

입력받은 수 : 변수명 st

StringTokenizer st = new StringTokenizer(br.readLine(), " ");

 

 

st를 변수명 temp에 배열로 집어넣는다 

for(int i=0; i<horse.length;i++){
    temp[i] = Integer.parseInt(st.nextToken());

 

각각을 배열로 만들어서 for문을 배열길이 총6만큼 반복 시켜서 

for문의 i인덱스번호만큼 각 지정 숫자끼리 빼는 것이다

그리고 마지막 출력을 공백 있는 정수나 str로 해야 하기에 배열로 그대로 출력하면 틀리니 주의

(필자가 이래서 틀림처림됨)

        for(int i=0; i<horse.length;i++){
            temp[i] = Integer.parseInt(st.nextToken());
            answer += horse[i] - temp[i] + " ";
        }

 

 

정답 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
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[] horse = {1,1,2,2,2,8};
        int[] temp = new int[6];
        String answer = "";

        for(int i=0; i<horse.length;i++){
            temp[i] = Integer.parseInt(st.nextToken());
            answer += horse[i] - temp[i] + " ";
        }
        System.out.println(answer);

    }
}
728x90
반응형
728x90

 

Scanner + String Class split() 방법을

BufferedReader+StringTokenizer으로 다시 풀어봄

 

BufferedReader의 readLine() 메소드로 입력을 받고 이 값을 담아둔 변수명인 br을 

StringTokenizer 안에 담아둬서 " "으로 구분자 지정하고 나눈다.

ex) 100 100 입력 받았으면 100 사이 공백을 기준으로 100, 100 두 수를 만들게 된다.

이 상태에서 배열에 담아 두 수를 다시 분리할 수 있도록 한다

이후에는 if문 조건

public void method01() throws IOException {
    // Step2-1 1330번 : 두 수 비교하기
    // 조건
    // 한 줄에 두 수 받기

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine()," ");

    int[] num = new int[2];
    for(int i=0; i < num.length;i++){
        num[i] = Integer.parseInt(st.nextToken());
    }
//        System.out.println(Arrays.toString(num));

    int num1 = num[0];
    int num2 = num[1];

    if(num1 > num2){
        System.out.println(">");
    }else if(num1 < num2){
        System.out.println("<");
    }else{
        System.out.println("==");
    }


}

 

728x90
반응형
728x90

 

문제 : 9498번: 시험 성적 (acmicpc.net)

 

9498번: 시험 성적

시험 점수를 입력받아 90 ~ 100점은 A, 80 ~ 89점은 B, 70 ~ 79점은 C, 60 ~ 69점은 D, 나머지 점수는 F를 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

 

풀이

스캐너 혹은 버퍼드리더로 숫자를 받는다
  - 버퍼드는 str만 받으므로 int로 형변환해야함
  - 또한, import문 넣을 때도 IOException도 같이 넣어줘야 컴파일 에러 안남
각 점수대 별로 if문으로 점수 분배

 

정답

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int score = Integer.parseInt(br.readLine());


        if(score >= 90){
            System.out.println("A");
        }else if(score >= 80){
            System.out.println("B");
        }else if(score >= 70){
            System.out.println("C");
        }else if(score >= 60){
            System.out.println("D");
        }else{
            System.out.println("F");
        }
    }
}

 

 

728x90
반응형
728x90

 

문제 : 1330번: 두 수 비교하기 (acmicpc.net)

 

1330번: 두 수 비교하기

두 정수 A와 B가 주어졌을 때, A와 B를 비교하는 프로그램을 작성하시오.

www.acmicpc.net

 

brain Storming
if문 사용
한 줄에 두 수 받기 뭐가 있을까
한 줄에 공백으로 두개 받고 구분자로 나누기? StringTokenizer
방법1 : Scanner + split()
방법2 : BufferedReader + StringTokenizer

 

풀이

일단 스캐너로 숫자1 공백 숫자2 이런식으로 입력을 받고

공백을 기준으로 split을 이용하여 나눠서 배열에 넣는다(split이 배열로 반환하기에 배열로 받아줘야함)

이후 배열의 인덱스번호로 두 수를 지정하고 int로 형변환 해주면서 각각 변수에 넣어주고 if문으로 조건을 주어서 출력했다

 

정답

Scanner + String Class split() 방법

import java.util.*;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        String num = sc.nextLine();

        String[] nums = num.split(" "); // String Class인 split()은 배열로 반환하므로, 배열로 받아야함


        // 배열로 받은 것을 인덱스 번호로 수 2개로 나눔
        int num1 =  Integer.parseInt(nums[0]);
        int num2 =  Integer.parseInt(nums[1]);

        if(num1 < num2){
            System.out.println("<");
        }else if(num1 > num2){
            System.out.println(">");
        }else {
            System.out.println("==");
        }

    }
}

 

 

728x90
반응형

+ Recent posts