파게로그
[백준 1002번] 터렛, 두 원의 교점의 개수 본문
문제 링크: 1002번 터렛
https://www.acmicpc.net/problem/1002
반지름이 r1, r2인 두 원은 다음과 같은 위치 관계를 가질 수 있다.
1. 서로 다른 두 점에서 만난다.
|r2-r1| < d < r2+r1
2. 한 점에서 접한다.
2-1. 외접
r1+r2 = d
2-2. 내접
|r2-r1| = d
3. 만나지 않는다.
3-1. 한 원이 다른 원의 외부에 있을 경우
d > r1+r2
3-2. 한 원이 다른 원의 내부에 있을 경우(반지름이 다른 동심원 포함)
d < |r2-r1|
4. 무수히 많은 점에서 만난다(반지름이 같은 동심원).
두 원의 중심이 같고, r1 = r2
그런데 이 문제를 풀 때, d를 구할 때에는 점과 점 사이의 거리 공식을 이용해야 하고, 이는 기본적으로 피타고라스 정리를 이용한 것이다. 곧, d를 구하기 위해서는 제곱근을 이용할 수밖에 없다.
이는 실수 자료형을 이용하게 하고, 곧 코드는 오차로 인한 오답의 위험성을 내포하게 된다. 이를 방지하고자 하는 것이 아니라 d와 r1+r2, r1-r2를 비교
d^2과 (r1+r2)^2, (r1-r2)^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));
StringBuilder sb = new StringBuilder();
int test = Integer.parseInt(br.readLine());
while (test-- > 0) {
StringTokenizer 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 sqd = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
int rs = (r1 + r2) * (r1 + r2);
int rd = (r1 - r2) * (r1 - r2);
if (x1 == x2 && y1 == y2 && r1 == r2) {
sb.append(-1);
} else if (sqd > rs) {
sb.append(0);
} else if (sqd == rs) {
sb.append(1);
} else if (rd < sqd) {
sb.append(2);
} else if (sqd == rd) {
sb.append(1);
} else {
sb.append(0);
}
sb.append('\n');
}
System.out.print(sb);
}
}
참고로, 아래 코드는 내가 PS를 처음 시작했을 때 짠 코드로서 오차를 고려하지 않았다. 통과는 하지만, 좋은 코드라고 할 수는 없다.
#include <iostream>
#include <cmath>
using namespace std;
int main(void) {
int x1, y1, r1, x2, y2, r2;
double d;
int cases; cin >> cases;
for (int i = 0; i < cases; i++) {
cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
d = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
int rdiff = r1 - r2 > 0 ? (r1-r2) : (-1) * (r1-r2);
if (d == 0 && r1 == r2) {
cout << -1;
} else if (d > r1 + r2) || d < rdiff) {
cout << 0;
} else if (d == r1 + r2) || d == rdiff) {
cout << 1;
} else if (d < r1 + r2) {
cout << 2;
}
cout << '\n';
}
return 0;
}
'콤퓨타 왕왕기초 > PS' 카테고리의 다른 글
[백준 10870번] 피보나치 (0) | 2020.10.30 |
---|---|
[백준 10872번] 팩토리얼 (0) | 2020.10.30 |
[백준 3053번] 택시 기하학 (0) | 2020.10.30 |
[백준 3009번] 네 번째 점 (0) | 2020.10.30 |
[백준 9020번] 골드바흐의 추측 (0) | 2020.10.30 |
Comments