본문 바로가기
PS

[C++] 백준 1002 - 터렛

by gamxong 2023. 2. 24.

난이도 : 실버 3

 

 

풀이 방법

 

나름 고민을 많이 했던 문제였다.
이거보다 난도가 있는 백준 1004 어린왕자 문제를 못풀었는데 이것도 온전히 자력으로 풀진 못했다.

자력으로 생각한 것은 두 점간의 거리(d)와 반지름 r1+r2를 비교하는 것이었다.
그렇게 함으로써, 접점의 개수를 찾으면 되는 간단한 문제라고 생각했다.

  1. d<r1+r2
  2. d==r1+r2
  3. d<r1+r2

의 경우로 생각했다.

 

하지만 테스트케이스 마지막 예시에서 실패하였다.
바로 원 내부에 원이 있는 경우가 고려되지 않았던 것이었다. 수학을 안한지 너무 오래돼서 고등학생 때 구했던 방식들을 되짚어 봤다.
그래서 (r1-r2) * (r1-r2) 의 식을 사용하면 되겠다라는 생각을 했는데 확신이 없었고, 결국 다른 사람의 코드를 봤다.
역시나 같은 방식으로 하였고, 문제를 해결할 수 있었다.

(r1-r2) (r1-r2) < d^2 < (r1+r2) (r1+r2)

 

 식으로 만족하면 2, 같아지면 1, 만족하지 않으면 0을 출력한다.
추가로 좌표가 같을 경우에는 반지름에 따라

  1. 모든 점에서 접하는 동일한 원 2개 -> -1 출력
  2. 접하지 않는 다른 원 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");
        }
    }
}

댓글