https://www.acmicpc.net/problem/7869
22/11/09
전형적인 수학, 기하학 문제로, 제2코사인 법칙을 사용하여 문제를 해결할 수 있다.
문제 접근 방식:
이 문제를 풀기 위해서는 먼저 제2코사인 법칙을 알아야 한다.
제2코사인 법칙이란, 어떤 삼각형의 세 변과 그 대각 사이에 성립되는 관계로, 위와 같은 식을 따른다.
따라서, 내가 예를 들어, 각 B를 구하고 싶으면 저 식 중 2번째 식을 변형하여 아래와 같이 구할 수 있다.
이 식을 이용할 것이다.
먼저, 원의 위치 관계에 따라 3가지 경우로 나뉜다.
1. 두 원이 서로 만나지 않을 때
즉, 두 원의 중심 사이의 거리가 두 원의 반지름의 합보다 크거나 같을 때이다.
이때에는 두 원이 겹치지 않으므로, 0.000을 출력해주면 된다.
2. 두 원이 서로 만날 때
이 경우 두 가지 경우로 나뉘게 된다.
2-1. 한 원이 다른 원에 완전히 들어갈 때
이 경우 작은 원의 넓이를 출력해준다.
2-2. 원과 원이 서로 겹칠 때 (일반적인 경우)
이 경우 겹치는 넓이를 출력해준다.
우리는 일반적인 경우를 살펴볼 것이다.
위의 그림을 보면, 우리는 원이 겹쳐지는 넓이를 두 원의 교점을 지나는 직선으로 이등분하여 구할 수 있다.
그림에서는 노란색 넓이와 파란색 넓이가 바로 그것이다.
노란색 넓이는 부채꼴 CAD의 넓이에서 삼각형 CAD의 넓이를 뺀 넓이와 같다.
따라서,
비슷한 이유로, 파란색 부분의 넓이는 다음과 같다.
따라서, 우리는 theta1과 theta2를 구하면 이 넓이를 구할 수 있다.
theta1과 theta2는 위의 제2코사인 법칙을 이용해서 구할 수 있다.(맨 위의 식을 참고하면 된다.)
따라서, 구한 theta1과 theta2를 위의 식 2와 식 3에 대입한 뒤, 식 2와 식 3을 합하면 답이 된다.
아래는 내가 위의 접근 방식과 같이 작성한 파이썬 코드이다. 더보기를 누르면 확인할 수 있다.
# 7869번 두 원
# 수학, 기하학
from math import *
x1, y1, r1, x2, y2, r2 = map(float, input().split())
if (x1-x2)**2 + (y1-y2)**2 >= (r1+r2)**2:
print('0.000')
else:
d = dist((x1, y1),(x2, y2))
if d + min(r1, r2) <= max(r1, r2):
r = min(r1, r2)
total = pi*r*r
else:
theta1 = 2*acos((r1*r1+d*d-r2*r2)/(2*r1*d))
theta2 = 2*acos((r2*r2+d*d-r1*r1)/(2*r2*d))
total = r1*r1*(theta1-sin(theta1))/2 + r2*r2*(theta2-sin(theta2))/2
print(f'{round(total, 3):.3f}')
'알고리즘 > 백준 문제 풀이' 카테고리의 다른 글
[Python] 16939번 2×2×2 큐브 (0) | 2022.11.10 |
---|---|
[Python] 11973번 Angry Cows (Silver) (0) | 2022.11.10 |
[Python] 25921번 건너 아는 사이 (0) | 2022.11.09 |
[Python] 25916번 싫은데요 (0) | 2022.11.09 |
[Python] 25915번 연세여 사랑한다 (0) | 2022.11.09 |