난이도 : 실버 3
풀이 방법
나름 고민을 많이 했던 문제였다.
이거보다 난도가 있는 백준 1004 어린왕자 문제를 못풀었는데 이것도 온전히 자력으로 풀진 못했다.
자력으로 생각한 것은 두 점간의 거리(d)와 반지름 r1+r2를 비교하는 것이었다.
그렇게 함으로써, 접점의 개수를 찾으면 되는 간단한 문제라고 생각했다.
- d<r1+r2
- d==r1+r2
- d<r1+r2
의 경우로 생각했다.
하지만 테스트케이스 마지막 예시에서 실패하였다.
바로 원 내부에 원이 있는 경우가 고려되지 않았던 것이었다. 수학을 안한지 너무 오래돼서 고등학생 때 구했던 방식들을 되짚어 봤다.
그래서 (r1-r2) * (r1-r2) 의 식을 사용하면 되겠다라는 생각을 했는데 확신이 없었고, 결국 다른 사람의 코드를 봤다.
역시나 같은 방식으로 하였고, 문제를 해결할 수 있었다.
(r1-r2) (r1-r2) < d^2 < (r1+r2) (r1+r2)
이 식으로 만족하면 2, 같아지면 1, 만족하지 않으면 0을 출력한다.
추가로 좌표가 같을 경우에는 반지름에 따라
- 모든 점에서 접하는 동일한 원 2개 -> -1 출력
- 접하지 않는 다른 원 2개 -> 0 출력
둘 중 하나이기 때문에 이 부분만 예외처리를 해준다.
최종 코드
#include <iostream>
#include <cstring>
using namespace::std;
int main(void){
int T = 0;
scanf("%d", &T);
for(int i=0; i<T; i++){
int x1,y1,r1,x2,y2,r2;
scanf("%d %d %d %d %d %d", &x1, &y1, &r1, &x2, &y2, &r2);
int diff = ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
int rr1 = (r1-r2) * (r1-r2);
int rr2 = (r1+r2) * (r1+r2);
if(diff == 0){
if(rr1 == 0){
printf("-1\n");
}else{
printf("0\n");
}
}else if(rr1 < diff && diff<rr2){
printf("2\n");
}else if(diff == rr1 || diff == rr2){
printf("1\n");
}else{
printf("0\n");
}
}
}
'PS' 카테고리의 다른 글
[C++] 백준 18870 - 좌표 압축 (0) | 2023.02.24 |
---|---|
[C++] 백준 2447 - 별찍기 - 10 (0) | 2023.02.24 |
[C++] 백준 11051 -이항 계수 2 (0) | 2023.02.24 |
[C++] 백준 11054 - 가장 긴 바이토닉 부분 수열 (0) | 2023.02.24 |
[C++] 백준 1932 - 정수 삼각형 (0) | 2023.02.24 |
댓글