개발하고/코딩테스트

[백준] 1002번 터렛

씩씩환 2021. 8. 2. 13:53

https://www.acmicpc.net/problem/1002

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net

1. 문제 접근

(x1, y1)을 중심으로 한 r1지름의 원과 (x2, y2)를 중심으로 한 r2지름의 원이 서로 겹치는 부분이 몇개인지 출력하면 되는 문제이다. 아래와 같이 그림으로 나타내면 x1, y1, r1, x2, y2, r2 값을 이용해 겹치는 부분이 0, 1, 2, 무한 인 경우로 나눌수 있다.

 

겹치는 부분이 0개인 경우

식 : d > r1 + r2 또는 d < r2 - r1

제곱식 : d² > (r1 + r2)² 또는 d² < (r1 - r2)²

*제곱식을 사용하면 d를 구할때 루트식을 사용할 필요도 없고 r1, r2크기비교를 할 필요도 없기에 코딩을 할때 더 효율적이다.

[그림1] 겹치는 부분이 0개인 경우(d > r1 + r2, d < r2 - r1)

 

겹치는 부분이 1개인 경우

식 : d = r1 + r2 또는 d = r2 - r1

제곱식 : d² = (r1 + r2)² 또는 d² = (r1 - r2)²

[그림2] 겹치는 부분이 1개인 경우(d = r1 + r2, d = r2 - r1)

 

하지만 d = r2 - r1일 때, [그림3]과 같이 r1 = r2라면 겹치는 부분은 무한개가 됨을 주의하자.

[그림3] 겹치는 부분이 무한개인 경우(d = r2 -r1)

 

겹치는 부분이 2개인 경우

식 : r2 - r1 < d < r1 + r2

제곱식 : (r1 - r2)² < d² < (r1 + r2)²

[그림4] 겹치는 부분이 2개인 경우(r2 - r1 < d < r1 + r2)

 

 

 

2. 코드

#include<iostream>
using namespace std;

#define SQUARED(x) ((x)*(x))

int main() {
    int T;
    cin >> T;
    for (int t = 0; t < T; t++) {
        int x1, y1, r1, x2, y2, r2;
        int dSqu, count;
        cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;

        dSqu = SQUARED(x1 - x2) + SQUARED(y1 - y2);

        if (dSqu > SQUARED(r1 + r2) || dSqu < SQUARED(r1 - r2)) // [그림1] 참조
            count = 0;
        else if (dSqu == SQUARED(r1 + r2))                      // [그림2] 참조
            count = 1;
        else if (dSqu == SQUARED(r1 - r2)) {                    // [그림2] 참조
            if (r1 == r2)                                       // [그림3] 참조
                count = -1;
            else                                               
                count = 1;
        }
        else                                                    // [그림4] 참조
            count = 2;

        cout << count << endl;
    }

    return 0;
}