수학에서는 흔한 접점 문제이다 접점이 2개이면 2, 접점이 1개면 1, 접점이 없으면 0, 접점이 무한대면 -1로 표현한다.
생각보다 꽤나 헷갈렸던 문제이다. 왜냐면 잘 기억이 안났었기 때문이다. 간단하게 머릿속으로 정리하고 다음과 같은 코드를 짜봤다:
import sys
import math
T = int(sys.stdin.readline())
for i in T:
x1, y1, r1, x2, y2, r2 = map(int, sys.stdin.readline().split())
d = math.sqrt((x1-x2)**2 + (y1-y2)**2)
diff = math.sqrt((r1-r2)**2)
if d > r1 + r2 or d < diff:
print(0)
elif d == 0 and r1 == r2:
print(-1)
elif d == r1 + r2 or d == diff:
print(1)
else:
print(2)
하지만 런타임 에러가 뜬다.
런타임 에러가 뜨는 이유는 여러가지가 있지만, 대표적으로는 다음과 같다 (www.acmicpc.net/board/view/22980):
- 배열에 할당된 크기를 넘어서 접근했을 때
- 전역 배열의 크기가 메모리 제한을 초과할 때
- 지역 배열의 크기가 스택 크기 제한을 넘어갈 때
- 0으로 나눌 때
- 라이브러리에서 예외를 발생시켰을 때
- 재귀 호출이 너무 깊어질 때
- 이미 해제된 메모리를 또 참조할 때
- 프로그램(main 함수)이 0이 아닌 수를 반환했을 때
나의 경우에는, 이중에 어떤거인지는 확실하지 않지만, 확실한 것은 line 10 ~ 13에 있는 문제다.
if d >r1 + r2 or d < diff일 경우 print(0)을 하라고 했는데, 이는 접점이 하나도 없는 경우이다.
하지만 아래 line 12 처럼 d가 0이면서도 diff < 0 인 경우도 해당되기 때문에 두가지 모두 해당 되는 경우가 발생한다.
따라서 다른 방식으로 접근해줘야 한다.
d ==0 일때와, d == 0 이 아닌 경우를 나누어줘서 if문을 실행시켜야한다. 결과는 다음과 같다:
import sys
T = int(sys.stdin.readline())
for i in range(T):
x1, y1, r1, x2, y2, r2 = map(int, sys.stdin.readline().split())
d1 = ((x1 - x2)**2) + ((y1 - y2)**2)
sum1 = (r1 + r2)**2
diff1 = (r1 - r2)**2
if d1 == 0:
if r1 == r2:
print(-1)
else:
print(0)
else:
if d1 == sum1 or d1 == diff1:
print(1)
elif d1 < sum1 and d1 > diff1:
print(2)
else:
print(0)
결론은 런타임 에러 때문에 애먹었던 문제이다.
'알고리즘 테스트 > 백준 문제풀이 및 해설' 카테고리의 다른 글
<백준 문제풀이 - 10869번> 파이썬 - 사칙연산 (0) | 2020.10.15 |
---|---|
<백준 문제풀이 - 10998번> 파이썬 - A x B (0) | 2020.10.15 |
<백준 문제풀이 - 1001번> 파이썬 - A-B (0) | 2020.10.14 |
<백준 문제풀이 - 2753번> 파이썬 - 윤년 (0) | 2020.10.13 |
<백준 문제번호: 9498번> 파이썬 - 시험성적 (0) | 2020.10.13 |