목차
코드
#include <iostream>
#include <math.h>
using namespace std;
int distance(int x1, int y1, int x2, int y2){
return ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
int main() {
int t; // test case
int x1, y1, r1; //조규현
int x2, y2, r2; //백승환
int dis, cnt;
cin >> t;
for(int i = 0; i < t; i++){
cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
dis = distance(x1, y1, x2, y2);
// 두 터렛이 동일한 위치에 있을 경우
if(dis == 0){
if(r1 == r2) cnt = -1;
else cnt = 0;;
}
// 두 터렛이 다른 위치에 있을 경우
else{
// 한 점에서 만나는 경우
if(dis == pow((r1 - r2),2) || dis == pow((r1 + r2), 2)) cnt = 1;
// 두 점에서 만나는 경우
else if(dis > pow((r1 - r2),2) && dis < pow((r1 + r2),2)) cnt = 2;
else cnt = 0;}
cout << cnt << "\n";
}
return 0;
}
사견
한 가지를 간과해서 계속해서 틀린 문제이다.
분명 모든 경우의 수를 고려한 것 같았고 타 블로그 해설을 보아도 나랑 생각이 동일한데 왜 자꾸 틀린걸까 싶었다.
우선, 이 문제에서 생각해야할 경우의 수에 대해 다루어 보자.
두 터렛의 위치가 동일한 경우
- 반지름의 길이가 같은 경우 두 원이 겹치면서 경우의 수가 무수히 많아진다. (-1)
- 반지름의 길이가 다른 경우 두 원의 겹치는 부분이 없다. (0)
두 터렛의 위치가 다른 경우
- 한 점에서 만나는 경우 외접, 내접 이렇게 두가지가 있다.
외접
내접
- 두 점에서 만나는 경우
- 만나지 않는 경우
이렇게 5가지이다.
나 같은 경우에는
두 점에서 만나는 경우일때
// 두 점에서 만나는 경우
else if(dis > pow((r1 - r2),2) && dis < pow((r1 + r2),2)) cnt = 2;
&& 를 사용해 주어야 하는데 ||로 하여 영문모를 오답을 얻었었다.
||을 하게 되면, 두 원이 만나지 않는 경우에도 조건을 충족하게 되어 오답이 된다.
또한,
두 점 사이의 거리를 구할때 제곱 후 sqrt함수, 즉 제곱근을 사용하여 틀린 사람도 있을것이다.
제곱근을 하게 되면 형변환을 하게되면서 값의 손실이 일어나 오답이 생길 수 있으므로
단순히 제곱간의 합을 통해 길이 비교를 하길 바란다.
추가 테스트 케이스
왜 틀리는 지 모르겠다면 이 테스트 케이스를 활용해 보기를 바란다.
입력
7
0 0 1 0 0 1 두 원이 겹치는 경우
0 0 1 0 0 3 중심 좌표는 같지만, 반지름이 다른경우
1 0 1 2 0 2 내접
-1 0 1 2 0 2 외접
1 0 2 3 0 3 두 점에서 만나는 경우
2 0 1 3 0 3 중심좌표가 다르고 만나지 않는다 1 (하나의 원이 다른원 안에 있는경우)
-2 0 1 3 0 3 중심좌표가 다르고 만나지 않는다 2 (하나의 원이 다른원 밖에 있는경우)
출력
-1
0
1
1
2
0
0
'공부 > 백준' 카테고리의 다른 글
3009번: 네 번째 점(백준 C++) (0) | 2020.10.16 |
---|---|
1085번: 직사각형에서 탈출(백준 C++) (0) | 2020.10.16 |
9020번: 골드바흐의 추측(백준 C++) (0) | 2020.10.15 |
4948번: 베르트랑 공준(백준 C++) (2) | 2020.10.15 |
1929번: 소수 구하기(백준 C++) (0) | 2020.10.15 |