반응형
https://www.acmicpc.net/problem/1002
풀이
처음 문제를 봤을 때 이해가 잘 안갔다..
검색을 하고나서야 이해가 갔다. 하나씩 이해해보겠다.
문제에선 두 개의 터렛 x, y 좌표와 류재명과의 r1, r2가 제공된다.
그렇다면 x, y를 기준으로 r1, r2의 반지름을 가진 원을 그릴 수 있다.
두 개의 원이 그러졌다면 A 터렛의 원과 B 터렛의 원의 접점 개수를 구하면 된다.
두 개의 원을 그렸을 때 생기는 접점의 개수에 대한 경우의 수는 몇 개일까?
위 그림처럼 여러가지가 있겠지만 4가지로 나눌 수 있다.
1.두 개의 접점이 생기는 경우
2. 한 개의 접점이 생기는 경우
3. 겹치지 않는 경우
4. 두 개의 원이 겹치는 경우
1. 두 개의 접점이 생기는 경우
: 그림 (1)
else if (dist > Math.pow(r2-r1,2) && dist < Math.pow(r1+r2,2)) {
arr[i] = 2;
}
2. 한 개의 접점이 생기는 경우
: 그림 (2), (3)
else if (Math.pow(r2-r1,2) == dist || Math.pow(r2+r1,2) == dist) {
arr[i] = 1;
}
3. 겹치지 않는 경우
: 그림 (4), (5), (6)
else if (Math.pow(r1+r2,2) < dist || Math.pow(r2-r1,2) > dist || dist == 0) {
arr[i] = 0;
}
4. 두 개의 원이 겹치는 경우
if (dist == 0 && r1 == r2) {
arr[i] = -1;
}
여기서 나오는 dist 변수는 두 개의 원 중점의 거리이다.
대부분의 풀이를 보면 double 형 또는 float 형으로 변수를 선언해서 Math.sqrt 를 사용했다.
double dist = Math.sqrt(Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));
하지만 이렇게 되면 정확한 값이 아니다. if-else 문을 통해서 간단한 연산을 해보면 쉽게 이해할 수 있다.
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
double a = 0.1;
double b = 0.2;
double c = 0.3;
if(a + b == c) System.out.print("참입니다.");
else System.out.print("거짓입니다.");
}
}
// 거짓입니다.
이러한 이유로 필자는 Math.sqrt 를 사용하지않고 Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2) 를 사용했다.
<최종코드>
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
int[] arr = new int[T];
for (int i=0; i<T; i++) {
st = new StringTokenizer(br.readLine());
int x1 = Integer.parseInt(st.nextToken());
int y1 = Integer.parseInt(st.nextToken());
int r1 = Integer.parseInt(st.nextToken());
int x2 = Integer.parseInt(st.nextToken());
int y2 = Integer.parseInt(st.nextToken());
int r2 = Integer.parseInt(st.nextToken());
// 두 개의 원 중점의 거리
int dist = (int)(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
// 두 개의 원이 겹치는 경우
if (dist == 0 && r1 == r2) {
arr[i] = -1;
}
// 두 개의 접점이 생기는 경우
else if (dist > Math.pow(r2-r1,2) && dist < Math.pow(r1+r2,2)) {
arr[i] = 2;
}
// 한 개의 접점이 생기는 경우
else if (Math.pow(r2-r1,2) == dist || Math.pow(r2+r1,2) == dist) {
arr[i] = 1;
}
// 겹치지 않는 경우
else if (Math.pow(r1+r2,2) < dist || Math.pow(r2-r1,2) > dist || dist == 0) {
arr[i] = 0;
}
}
for (int num : arr) {
System.out.println(num);
}
}
}
반응형
'알고리즘 > 구현 & 그리디 & 브루트포스' 카테고리의 다른 글
[백준]JAVA - 11399번: ATM (0) | 2022.10.20 |
---|---|
[백준]JAVA - 1052번: 물병 (0) | 2022.10.08 |
[백준]JAVA - 1652번: 누울 자리를 찾아라 (0) | 2022.09.26 |
[백준]JAVA - 1085번: 직사각형에서 탈출 (0) | 2022.09.26 |
[백준]JAVA - 1475번: 방 번호 (0) | 2022.09.22 |