[BaekJoon] 3053번 - 택시 기하학 (java)

📌 1. 문제

👉 문제 바로가기

- 조건

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


- 문제

19세기 독일 수학자 헤르만 민코프스키는 비유클리드 기하학 중 택시 기하학을 고안했다.
택시 기하학에서 두 점 T1(x1,y1), T2(x2,y2) 사이의 거리는 다음과 같이 구할 수 있다.
D(T1,T2) = |x1-x2| + |y1-y2|
두 점 사이의 거리를 제외한 나머지 정의는 유클리드 기하학에서의 정의와 같다.
따라서 택시 기하학에서 원의 정의는 유클리드 기하학에서 원의 정의와 같다.
원: 평면 상의 어떤 점에서 거리가 일정한 점들의 집합
반지름 R이 주어졌을 때, 유클리드 기하학에서 원의 넓이와, 택시 기하학에서 원의 넓이를 구하는 프로그램을 작성하시오.



- 입력

첫째 줄에 반지름 R이 주어진다. R은 10,000보다 작거나 같은 자연수이다.



- 출력

첫째 줄에는 유클리드 기하학에서 반지름이 R인 원의 넓이를, 둘째 줄에는 택시 기하학에서 반지름이 R인 원의 넓이를 출력한다. 정답과의 오차는 0.0001까지 허용한다.



- 예제

  입력      출력  
1 3.141593
2.000000
21 1385.442360
882.000000
42 5541.769441
3528.000000





📌 2. 풀이


2-0. 알고리즘

여기서 말하는 택시 기하학이란 맨해튼 거리 와 같은 말이다.
위키백과에서 말하는 맨해튼 거리는 아래와 같다.

image

오른쪽에 있는 그림을 더 자세히 보자.
image
여기서 빨간색, 파란색, 노란색 선은 가장 짧은 맨해튼 거리이다.
점까지 대각선으로 가로질러 갈 수 없고, 가로 또는 세로로만 이동가능한 최단 거리를 의미한다.
택시 기하학에서의 거리는 D(T₁, T₂) = |𝑥₁ - 𝑥₂| + |y₁ - y₂|

초록색 선은 가장 짧은 유클리드 거리이다.
우리가 평소 알고있는 ‘거리’의 개념이다.
유클리드 기하학에서의 거리는 D(T₁, T₂)² = (𝑥₁ - 𝑥₂)² + (y₁ - y₂)²


이제 원의 넓이를 한번 구해보자.
r (반지름) 이 4 라고 예를 들어보자.

유클리드 기하학에서 원은 아래와 같다.
image
원의 넓이 = 𝜋𝑟²
               = 4 x 4 x 𝜋
               = 16𝜋



그렇다면 택시기하학에서 원의 넓이는 어떻게 될까?
위의 문서를 보면 “맨해튼 거리의 원은 중심 점에서 반지름이라고 불리는 일정한 거리만큼 떨어져 있는 점들의 집합” 이라고 한다.
image
위의 그림처럼 맨해튼 거리에서 원은 45° 기울어진 정사각형이다.
원의 넓이 = 2𝑟²
               = 2 × 4 × 4
               = 32





이제 2개의 입력방식을 사용해서 결과를 출력한다.

  1. Scanner 클래스
  2. BufferedReader 클래스




2-1. Scanner 클래스

Math 클래스의 min() 을 사용해 최솟값을 구한다.

import java.util.Scanner;

public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        
        int r = sc.nextInt();
        
        System.out.println(Math.PI*r*r);
        System.out.println(2*r*r);
    }
}

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

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

public static final double PI = 3.14159265358979323846;
double 형과 int 형을 연산하면 큰 범위를 가지는 데이터 타입으로 결과가 자동으로 형변환된다.
따라서, Math.PI*r*r 의 결과는 double 형으로 반환되고 오차 범위는 0.0001 이므로 문제없다.



[여기서 잠깐!]

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




2-2. BufferedReader 클래스 사용

if 조건문 을 사용해 최솟값을 구한다.

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)); 
        
        int r = Integer.parseInt(br.readLine());

        System.out.println(Math.PI*r*r);
        System.out.println(2*r*r);
    }
}

readLine() 메서드를 사용해 입력받은 값을 한 줄 통째로 읽어 String 으로 반환한다.

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



[여기서 잠깐!]

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






📌 3. Scanner VS BufferedReader 성능 비교

image

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





관련 페이지

Categories:

Updated:

Leave a comment