[BaekJoon] 4153번 - 직각삼각형 (java)

1. 문제

👉 문제 바로가기

- 조건

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


- 문제

과거 이집트인들은 각 변들의 길이가 3, 4, 5인 삼각형이 직각 삼각형인것을 알아냈다. 주어진 세변의 길이로 삼각형이 직각인지 아닌지 구분하시오.


- 입력

입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다. 각 테스트케이스는 모두 30,000보다 작은 양의 정수로 주어지며, 각 입력은 변의 길이를 의미한다.

- 출력

각 입력에 대해 직각 삼각형이 맞다면 "right", 아니라면 "wrong"을 출력한다.

- 예제

  입력      출력  
6 8 10
25 52 60
5 12 13
0 0 0
right
wrong
right





2. 풀이

2-0. 알고리즘

세 변을 이루는 삼각형이 직각삼각형인지 알기 위해서는
a² + b² = c² 인지 확인해야 한다.

그러나 주의해야 할 점이 있다!!!
입력되는 값 중 어느 값이 대각선인지 알 수 없기 때문에, 3가지 조건을 모두 체크해서 맞는 경우를 찾아야 한다.




2개의 입력방식과 3가지 출력방식을 사용해서 결과를 출력한다.

  1. Scanner 클래스
  2. BufferedReader 클래스
    ① System.out.println();
    ② BufferedWriter
    ③ StringBuilder

2-1. Scanner 클래스

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        
        while(true){
            int a = sc.nextInt();
            int b = sc.nextInt();
            int c = sc.nextInt();
            
            // 0 0 0 을 입력받으면 종료
            if(a==0 && b==0 && c==0) break;
            
            if(Math.pow(a,2)+Math.pow(b,2)==Math.pow(c,2)){
                System.out.println("right");
            }else if(Math.pow(b,2)+Math.pow(c,2)==Math.pow(a,2)){
                System.out.println("right");
            }else if(Math.pow(c,2)+Math.pow(a,2)==Math.pow(b,2)){
                System.out.println("right");
            }else{
                System.out.println("wrong");
            }
        }
    }
}

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

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

Math 클래스의 pow() 를 사용해 거듭제곱 값 을 구한다.
예를 들어 Math.pow(5,3) 의 경우, 을 의미한다.



[여기서 잠깐!]

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




2-2. BufferedReader 클래스 사용

3가지 출력 방식으로 문제를 풀어보고 비교해보자.

     ① System.out.println()
     ② BufferedWriter
     ③ StringBuilder



문자열 분리 방법으로는 StringTokenizer 클래스를 사용한다.

StringTokenizer st = new StringTokenizer(문자열,구분자)

만약 구분자가 없으면 " "(공백)을 기준으로 분리한다.
분리된 각각의 데이터를 "토큰" 이라고 하며 nextToken() 함수 를 사용해 순서대로 호출할 수 있다.



① BufferedReader + System.out.println()

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));
        
        while(true){
            StringTokenizer st = new StringTokenizer(br.readLine());
            
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());

            // 0 0 0 을 입력받으면 종료
            if(a==0 && b==0 && c==0) break;
            
            if(Math.pow(a,2)+Math.pow(b,2)==Math.pow(c,2)){
                System.out.println("right");
            }else if(Math.pow(b,2)+Math.pow(c,2)==Math.pow(a,2)){
                System.out.println("right");
            }else if(Math.pow(c,2)+Math.pow(a,2)==Math.pow(b,2)){
                System.out.println("right");
            }else{
                System.out.println("wrong");
            }
        }
    }
}

Integer.parseInt()을 사용해 st.nextToken()으로 읽어온 String형 데이터를 int형으로 변환시켜준다.





② BufferedReader + BufferedWriter

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
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));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        while(true){
            StringTokenizer st = new StringTokenizer(br.readLine());
            
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            
            if(a==0 && b==0 && c==0) break;
            
            if(Math.pow(a,2)+Math.pow(b,2)==Math.pow(c,2)){
                bw.write("right");
            }else if(Math.pow(b,2)+Math.pow(c,2)==Math.pow(a,2)){
                bw.write("right");
            }else if(Math.pow(c,2)+Math.pow(a,2)==Math.pow(b,2)){
                bw.write("right");
            }else{
                bw.write("wrong");
            }
            bw.write("\n");
        }
        bw.flush();
        bw.close();
    }
}

BufferedWriter 클래스의 write() 메소드는 데이터를 내부 버퍼에 저장하고, flush() 메소드 를 사용해 버퍼를 비우고 데이터를 출력한다.

BufferedWriter 클래스의 write() 메소드는 단독으로 int 형 값만 넣을 경우 아스키 코드값으로 인식되기 때문에 다른 문자가 출력된다. 때문에 반드시 문자열과 int 형을 함께 넣어줘야 int 값을 제대로 출력할 수 있다.



[여기서 잠깐!]

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





③ BufferedReader + StringBuilder

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));
        StringBuilder sb = new StringBuilder();
        
        while(true){
            StringTokenizer st = new StringTokenizer(br.readLine());
            
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            
            if(a==0 && b==0 && c==0) break;
            
            if(Math.pow(a,2)+Math.pow(b,2)==Math.pow(c,2)){
                sb.append("right");
            }else if(Math.pow(b,2)+Math.pow(c,2)==Math.pow(a,2)){
                sb.append("right");
            }else if(Math.pow(c,2)+Math.pow(a,2)==Math.pow(b,2)){
                sb.append("right");
            }else{
                sb.append("wrong");
            }
            sb.append("\n");
        }
        System.out.println(sb);
    }
}

StringBuilder 클래스는 문자열을 동적으로 조작하기 위한 클래스로, append() 를 사용해 문자열을 추가하여 새로운 문자열을 생성한다.

append() 안에 “\n”를 더하기 연산하지 않고 위와 같이 분리해서 쓰면 타입 변환과 문자열 연결 연산이 추가적으로 발생하지 않고 StringBuilder에 직접 추가하기 때문에 보다 더 효율적이고 빠르다.





3. 성능 비교

image

위에서 부터 순서대로

BufferedReader + StringBuilder
BufferedReader + BufferedWriter
BufferedReader + System.out.println()
Scanner

위와같이 입력 메소드와 알고리즘 구현 방법에 따라 시간이 달라질 수 있다.

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

출력의 경우 이 문제에서는 시간이 모두 같다.
테스트케이스는 30,000 이하라고 했으나, 출력할 데이터가 적었는지 성능은 비슷하다.





관련 페이지

Categories:

Updated:

Leave a comment