ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 1002번 터렛
    알고리즘 2022. 6. 2. 18:34

    출처 링크:

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

     

     

    열심히 경우를 고려하였지만 쉽지 않았다.

     

    /*
    r의 위치와의 관계
    
    1) x좌표는 같고 y좌표만 차이나는 경우
    2) y좌표는 같고 x좌표만 차이나는 경우
    일직선상에 있는지 아닌지 판별 필요
    
    3) x, y 좌표 둘 다 차이나는 경우
    => 피타고라스 정리 활용 a**2 + B**2 = c**2
    */
    
    // 0 0 13 40 0 37
    
    const x1 = 0
    const y1 = 0
    const r1 = 13 // 류재명과의 거리
    const x2 = 40
    const y2 = 0
    const r2 = 37 // 류재명과의 거리
    
    if (y1 === y2) {
      // 일직선상에 있는지 판단
      // 일직선상에 있다면 y좌표가 똑같을 것
      // 일직선상에 있다면
      if (x1 <= x2) {
    
        if (r){
          x2 - x1 
        }
          
      } else {
    
        x1 - x2
      }
      
    }
    
    // 그런데 생각해보면 일직선상에 있어도 두 좌표 사이에 마린이 있는 경우와 어느 한좌표 보다
    // 바깥에 마린이 있는 경우까지 있다.. if문을 이렇게 많이 쓰는 것 말고 방법이 있을 듯 한데..

     

    그래서 답변들을 참조하였고, 특히 두 원이 주어졌을 때 둘의 위치관계가 어떤지에 대해서는 아래 블로그를 참고하였다.

     

    두원이 만나지 않는 경우(외부, 내부), 한점에서 만나는 경우(외접, 내접), 두점에서 만나는 경우

    https://mathbang.net/101

     

    해당 블로그의 설명대로 한다면 어떠한 경우든 아래의 로직으로 구할 수 있었다...

     

    solution();
    
    function solution() {
        let x1 = 0
        let y1 = 0
        let x2 = 40
        let y2 = 0
        let range = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
        // 피타고라스 정리, a제곱 더하기 b제곱의 루트는 c 제곱의 루트, 즉, c와 같음 => c는 두 원의 중심거리
        let round1 = 13
        let round2 = 37
        if (range === 0) {
          // 같은 위치에 있을 때
          if (round1 !== round2) {
            // 반지름이 같지 않을 때
            console.log(0);
          } else if (round1 === round2) {
            //반지름이 같을 때
            console.log(-1);
          }
        } else if (range < round1 + round2) {
          // 두 원의 중심거리가 두 반지름의 합보다 작을 때
          if (range + round1 < round2) {
            // 원 안에 다른 원이 있지만 내접하지 않는 경우
            console.log(0);
          } else if (range + round2 < round1) {
            // 원 안에 다른 원이 있지만 내접하지 않는 경우
            console.log(0);
          } else if (range + round1 === round2) {
            // 두 원의 중심선 + 반지름 = 다른 반지름의 거리 === 내접
            console.log(1);
          } else if (range + round2 === round1) {
            // 같음
            console.log(1);
          } else {
            console.log(2); // 두 개의 교차점, 두 반지름의 차보다 크고 두 반지름의 합보다는 작은 경우
          }
        } else if (range === round1 + round2) {
          // 두 중심선의 거리 === 두 원의 반지름의 합 == 외접
          console.log(1);
        } else if (range > round1 + round2) {
          // 두 중심선의 거리 > 두 원의 반지름의 합  == 접하지 않음
          console.log(0);
        }
    }

     

    그렇게 하여 제출할 때는 다음과 같다.

     

    const fs = require("fs");
    let input = fs.readFileSync('dev/stdin').toString().split("\n");
    
    input.pop();
    
    //console.log(input)
    
    solution(input);
    
    function solution(A) {
      let testCount = +A[0];
      for (let i = 1; i <= testCount; i++) {
        A[i] = A[i].split(" ").map((item) => +item);
        let x1 = A[i][0];
        let y1 = A[i][1];
        let x2 = A[i][3];
        let y2 = A[i][4];
        let range = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
        //console.log(range)
        let round1 = A[i][2];
        let round2 = A[i][5];
        if (range === 0) {
          // 같은 위치에 있을 때
          if (round1 !== round2) {
            // 반지름이 같지 않을 때
            console.log(0);
          } else if (round1 === round2) {
            //반지름이 같을 때
            console.log(-1);
          }
        } else if (range < round1 + round2) {
          // 두 원의 중심거리가 두 반지름의 합보다 작을 때
          if (range + round1 < round2) {
            // 원 안에 다른 원이 있지만 내접하지 않는 경우
            console.log(0);
          } else if (range + round2 < round1) {
            // 원 안에 다른 원이 있지만 내접하지 않는 경우
            console.log(0);
          } else if (range + round1 === round2) {
            // 두 원의 중심선 + 반지름 = 다른 반지름의 거리 === 내접
            console.log(1);
          } else if (range + round2 === round1) {
            // 같음
            console.log(1);
          } else {
            console.log(2); // 두 개의 교차점
          }
        } else if (range === round1 + round2) {
          // 두 중심선의 거리 === 두 원의 반지름의 합 == 외접
          console.log(1);
        } else if (range > round1 + round2) {
          // 두 중심선의 거리 > 두 원의 반지름의 합  == 접하지 않음
          console.log(0);
        }
      }
    }

     

    중고등학교때 배운 적이 있는 것 같은 내용들이었다.

    이들의 관계만 잘 이해한다면 그대로 적용하는 것이기에 그리 어렵지 않게 다룰 수 있다.

     

    참조 답변 링크:

    https://hell-of-company-builder.tistory.com/138

Designed by Tistory.