[BOJ] 1002 터렛

이강혁·2024년 8월 18일
0

백준

목록 보기
21/36
post-custom-banner

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

점이 두 개 주어지고, 찾으려고 하는 대상과 두 점 사이의 거리가 주어질 때, 대상이 존재할 수 있는 위치가 몇 가지가 되는 지 찾는 문제이다.

코드 1 - 포기

for _ in range(int(input())):
  x1, y1, r1, x2, y2, r2 = map(int, input().split())
  
  a = 2 * (x1 - x2)
  b = 2 * (y1 - y2)
  c = x1 ** 2 - x2 ** 2 + y1 ** 2 - y2 ** 2 - r1 ** 2 + r2 ** 2
  
  if y1 != y2:
    count = 0
    for x in range(-10000, 10001):
      y = (a * x + c) / b
      if (x-x1) ** 2 + (y-y1) ** 2 == r1 ** 2 and (x-x2) ** 2 + (y - y2) ** 2 == r2 **2:
        count += 1
        if count > 2:
          count = -1
          break
    
  else:
    x = (r1 ** 2 - r2 ** 2 + x2 ** 2 - x1 ** 2) / 2 * (x2 - x1)
    
    if r1 ** 2 < (x - x1) ** 2:
      count = -1
    elif ( r1 ** 2 - (x-x1) ** 2) ** 0.5 - int(( r1 ** 2 - (x-x1) ** 2) ** 0.5) == 0:
      count = 1
    else:
      count = 2
    
    
    
    
        
  print(count)

처음에는 원 방정식을 활용해서 두 원의 교점을 찾으려고 접근했다.
그래서 원 방정식의 해를 구하려고 저렇게 코드를 만들었는데 하다가 포기했다. 손으로 써도 오래 걸릴 것 같은데 코드로만 방정식을 해결하려고 하니까 너무 복잡해질 것 같아서 버리고 다른 방법을 찾아보기로 했다.

코드 2

for _ in range(int(input())):
  x1, y1, r1, x2, y2, r2 = map(int, input().split())
  
  dist = ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
  if x1 == x2 and y1 == y2 and r1 == r2:
    print(-1)
  elif r1 + r2 == dist or max(r2, r1) == min(r2, r1) + dist:
    print(1)  
  elif r1 + r2 > dist and max(r2, r1) < min(r1, r2) + dist:
    print(2)
  else:
    print(0)

두 점 사이의 거리와 원의 반지름의 관계를 이용해서 해결했다.

두 원이 일치하는 경우를 먼저 걸러주었다.

그 다음 두 점 사이의 거리가 두 원의 반지름의 합과 같거나(외접) 혹은 큰 반지름이 작은 반지름의 길이와 두 점 사이의 거리와 같다면(내접) 경우의 수는 1로 출력하였다.

두 반지름의 합이 점 사이의 거리보다 크고 큰 반지름이 점 사이의 거리와 작은 반지름의 합보다 작은 경우 교점이 두 개 생기는 것으로 출력하였다.

그 외 경우는 원이 만나지 못하는 것으로 결정하고 0을 출력하였다.


처음에는 원의 교점을 구하면 되겠다고 무턱대고 방정식을 해결하고자 했는데 문제에서 요구한 조건은 점의 위치를 찾는 것이 아니라 경우의 수를 찾는 것이기에 더 나은 방법을 생각해보고 접근해야했다.

신중하게 접근하는 습관이 필요할 것 같다.

profile
사용자불량
post-custom-banner

0개의 댓글