[1. 문제 설명]
https://www.acmicpc.net/problem/1002
[2. 풀이 접근]
중심 좌표가 있고, 거리가 있다 => 중심 좌표로 부터 동일한 거리 => 원
두 개의 원이 있고, 이 원의 관계성을 이용하여 해의 개수를 판별 한다.
두 원의 중심 간의 거리의 제곱을 d 라하면 (정수 값으로 비교하기 위함)
1) 두 원의 중심이 같을 때
=> 두 원의 반지름이 같으면, 해의 개수가 무한대 (특수해)
=> 두 원의 반지름이 다르면, 해의 개수 없음
2) 작은 원의 중심이 큰 원 바깥에 있을 때
=> 두 원이 만나지 않음, 해의 개수 없음 (d > r1+r2)
=> 두 원이 접함, 해의 개수는 1개 (d == r1+r2)
=> 두 원이 두점에서 교차 함, 해의 개수는 2개 (d < r1+r2)
3) 작은 원의 중심이 큰 원 안쪽에 있을 때
=> 두 원이 만나지 않음, (d < abs(r2 - r1))
=> 두 원이 접합, (d = abs(r2 - r1))
=> 두 원이 두점에서 교차, (d > abs(r2 - r1))
단, d 는 사실 sqrt(d2) 이므로, 정수 비교를 위해 수식을 적절히 변형 후,
제곱하여 정수 단위 비교를 하는 편이 적절히 보임
그림으로 보면 아래와 같다.
1)
2)
3)
[3. 코드]
const fs = require("fs");
const process = require("process");
const inputs = fs.readFileSync(process.stdin.fd).toString().trim().split("\n");
const N = Number(inputs[0]);
const result = [];
for (let idx=1; idx<=N; idx++) {
const input = inputs[idx].split(" ").map(Number);
let [x1, y1, r1] = [input[0], input[1], input[2]];
let [x2, y2, r2] = [input[3], input[4], input[5]];
if (r1 > r2) {
// swap 할 때 주의해야 함.
// 아래는 원하는 대로 swap 되지 않음.
// [x1, y1, r1] = [x2, y2, r2]
[x1, y1, r1, x2, y2, r2] = [x2, y2, r2, x1, y1, r1];
}
// r1 < r2
// 항상 r2 가 더 큰 원이고,
// r2 에 해당하는 원의 중심은 원점으로 가정하겠다.
// 이에 맞춰 r1 에 해당하는 원의 중심을 옮긴다.
x1 -= x2;
y1 -= y2;
x2 = 0;
y2 = 0;
const d_sq = (x1**2 + y1**2); // 두 원의 중심 간의 거리의 제곱
const s2 = (r1+r2) ** 2; // 반지름 합의 제곱
const s3 = (r2-r1) ** 2; // 반지름 차의 제곱
if (d_sq == 0) { // 중심이 같을 때,
if (r1 == r2) { // 반지름이 같음, 무한한 점이 겹침
result.push(-1);
} else { // 반지름이 다름, 겹치는 구간 없음
result.push(0);
}
} else if (d_sq > r2**2) { // 작은 원의 중심이 큰 원의 외부에 있을 때,
if (d_sq == s2) { // 두 원이 접할 때
result.push(1);
} else if (d_sq > s2) { // 두 원이 만나지 않음
result.push(0);
} else { // 두 원이 두 점에서 교차함
result.push(2);
}
} else { // 작은 원의 중심이 큰 원의 내부에 있을 때,
if (d_sq == s3) { // 두 원이 접함
result.push(1);
} else if (d_sq < s3) { // 두 원이 만나지 않음
result.push(0);
} else { // 두 원이 두 점에서 교차함
result.push(2);
}
}
}
// 한번에 출력하는 것이 시간에서 이득을 볼 수 있다.
// 기본적으론 출력 버퍼를 매번 flush 하기 때문이다.
console.log(result.join("\n"));
'알고리즘 > Baekjoon' 카테고리의 다른 글
... [1762] (0) | 2025.06.10 |
---|---|
mo`s. [13548] (0) | 2025.06.04 |
제곱근 분할법. [13546] (0) | 2025.06.03 |
차분 배열 [19551] (0) | 2025.05.21 |
라빈-카프 [3033] (1) | 2025.05.17 |