코딩 테스트/백준

[백준][silver4][JAVA]터렛

갓생사는 김초원의 개발 블로그 2021. 3. 28. 20:15

[문제 설명]

www.acmicpc.net/problem/1002

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net

 

[풀이 과정]

조규현, 백승환 각 좌표와 떨어진 거리를 반지름으로 원을 그려보면 두 원이 만나는지 여부를 알 수 있다. 

두 원이 만나는 접점의 개수가 류재명이 있을 수 있는 좌표의 개수이다. 

 

<두 원의 접점의 개수>

총 6가지 경우가 있다. 

1. 두 점에서 만남 한 점에서 만남
2. 외접 3. 내접
반지름의 차 < 두 중점 거리 < 반지름의 합 
( r2 - r1 <d < r1 + r2)
두 중점 거리 = 반지름의 합
(d = r1 + r2)
두 중점 거리 = 반지름의 차이 and d!=0
(d = r2 - r1 and d!=0)
만나지 않는 경우 무수히 많음
외부에서  내부에서  
4. 두 중점의 거리 > 반지름의 합
(d > r1 + r2)
5. 두 중점 거리 < 반지름의 차이 
(d < r2 - r1)
6. 두 중점의 거리 = 0 이고 두 반지름이 같은 경우
(d=0 and r1 = r2)

 

* 느낀점:

수학을 다시 꺼내보다니..

좌표와 반지름이 주어진다면 원을 이용하여 푸는 문제다. 

원에 대한 공식을 줄줄히 욀 수는 없고, 비슷한 문제가 나왔을 경우 이런 방법으로 풀어야 한다..는 것을 바로 생각하면 될 것 같다. 

 

[Java code]

package com.algorithm.baekjoon.silver4;

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

public class Test01 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        StringTokenizer st;
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());

            int[] loc1 = {Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())};
            int r1 = Integer.parseInt(st.nextToken());

            int[] loc2 = {Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())};
            int r2 = Integer.parseInt(st.nextToken());

            solution(loc1, r1, loc2, r2);
        }
    }

    public static void solution(int[] loc1, int r1, int[] loc2, int r2) {
        // 두 원의 중점 거리 (조규현, 백승환)
        double d = Math.sqrt(Math.pow(loc1[0] - loc2[0], 2) + Math.pow(loc1[1] - loc2[1], 2));

        int plus = r1 + r2;
        int minus;
        if (r1 >= r2) {
            minus = r1 - r2;
        } else {
            minus = r2 - r1;
        }

        // 두 점에서 만나는 경우
        if (minus < d && d < plus) {
            System.out.println(2);
            return;
        }

        // 한 점에서 만나는 경우
        if (plus == d || (minus == d && d != 0)) {
            System.out.println(1);
            return;
        }

        // 만나지 않는 경우
        if (plus < d || d < minus) {
            System.out.println(0);
            return;
        }

        // 무수히 많은 경우
        System.out.println(-1);
    }
}