Byeo

boj 7869 - 두 원 본문

알고리즘 (Algorihtm)/백준

boj 7869 - 두 원

BKlee 2021. 12. 30. 03:19
반응형

목차

개요

설명

코드

풀이 과정

개요

삼각함수를 이용해서 겹쳐진 두 원의 넓이를 구하는 문제입니다. 두 원이 존재할 수 있는 방법은 다음과 같이 세 가지 경우가 있습니다.

1) 두 원이 완전히 겹쳐지지 않은 경우

2) 일부가 겹친 경우

3) 한 원이 다른 원에 완전히 속한 경우

설명

먼저, 두 원의 원점 사이의 거리는 d=(x1x2)2+(y1y2)2 입니다.

1) 두 원이 완전히 겹쳐지지 않은 경우

두 원이 겹쳐지지 않기 위한 조건은 d>r1+r2 입니다. 이 때, 겹치는 넓이는 0 입니다.

2) 일부가 겹친 경우

두 원이 일부만 겹치기 위한 조건은 |r1r2|<d<r1+r2 입니다.

이 때, 부채꼴을 이루는 각 αβ는 다음과 같습니다. 풀이 과정은 페이지 하단을 참고해주세요.

α=2cos1((l2+r21r22)/(2lr1)),β=2cos1((l2+r22r21)/(2lr2))

다음 r1 입장에서 계산할 때, 노란색 색칠된 영역의 넓이를 구하고 2배를 하면 됩니다.

이 색칠된 부분의 넓이 S1은 다음과 같습니다.

S1=(r21αr21α)/2

마찬가지로 반대 부분의 넓이 S2도 다음과 같습니다.

S2=(r22βr22β)/2

따라서 정답은 다음과 같이 정리가 가능합니다.

Ans=S=S1+S2=r21(αsin(α))+r22(βsin(β))

참고

각도가 θ인 부채꼴의 넓이 = r2θ/2,

두 변의 길이가 a,b이고, 그 변의 사이 각이 θ인 삼각형의 넓이 = abθ/2

3) 한 원이 다른 원에 완전히 속한 경우

두 원점 사이의 거리 d|r1r2| 보다 작아지면, 둘 중 반지름이 작은 원이 큰 원 내에 속해 있다는 의미입니다.

이 때, 겹치는 넓이는 min(r1,r2)2π 입니다.

코드

#include<stdio.h>
#include<math.h>

inline double pow(double a){
        return a*a;
}
inline double min(double a, double b){
        return a>b? b:a;
}
int main(){

        double x1,y1,r1, x2,y2,r2;
        scanf("%lf %lf %lf %lf %lf %lf",&x1, &y1, &r1, &x2, &y2, &r2);

        double l=sqrt(pow(x2-x1)+pow(y2-y1));
        double ANS = 0;
        if(r1+r2<=l){
                ANS = 0;
        }else if(r1+r2>l && abs(r1-r2)<l){
                double a = 2*acos((pow(l)+pow(r1)-pow(r2))/(2*l*r1));
                double b = 2*acos((pow(l)+pow(r2)-pow(r1))/(2*l*r2));
                ANS = pow(r1)*(a-sin(a))+pow(r2)*(b-sin(b));
                ANS /=2;
        }else{
                ANS = pow(min(r1,r2))*M_PI;
        }
        printf("%.3lf\n",ANS);
}

풀이과정

고교때 배운 cos 법칙과 삼각함수 합곱 공식은 거의 기억이 나지 않는 수준에 도달했습니다. 대신에 간단한 몇 가지 사실을 이용해서 계산하면 식을 유도할 수 있습니다.

이 교차점에서 d는 우리가 이미 계산해서 알 수 있습니다. ( d=(x1x2)2+(y1y2)2 )

1) 높이 h를 이용

높이 h를 이용하면 다음과 같은 식을 유도할 수 있습니다.

h=r1sin(α/2)=r2sin(β/2) 

2) d의 표현식

두 원점 사이의 거리 d는 각 원의 반지름에 cos하여 더한 값과 같습니다.

d=r1cos(α/2)+r2cos(β/2) 

3) 연립

(1)에서 sin2(α)+cos2(α)=1 임을 이용하면 다음과 같이 변경할 수 있습니다.

h2=r21 sin2(α/2)=r22 sin2(β/2)r21(1cos2(α/2))=r22(1cos2(β/2))r21r21 cos2(α/2)=r22r22 cos2(β/2)

 

(5)를 정리하면 다음 식을 얻을 수 있습니다.

 

r21 cos2(α/2)=r21r22+r22 cos2(β/2)

 

(2)에서 우선 계산의 편의를 위해 d를 제곱해줍니다.

d2=r21 cos2(α/2)+r22 cos2(β/2)+2r1r2 cos(α/2) cos(β/2)

 

여기서 식 (6)을 대입하면

d2=r21r22+2r22 cos2(β/2)+2r1r2 cos(α/2) cos(β/2)d2r21+r22=2r22 cos2(β/2)+2r1r2 cos(α/2) cos(β/2)(d2r21+r22)/2r2=r2 cos2(β/2)+r1 cos(α/2) cos(β/2)=cos(β/2)(r2 cos(β/2)+r1 cos(α/2))

 

(11)에서 기존의 식 (2)를 대입하면

(d2r21+r22)/2r2=cos(β/2)(d)(d2r21+r22)/2dr2=cos(β/2)

 

이제 마지막 식에서 cos 역함수를 취해주면 다음과 같은 결과를 얻어낼 수 있습니다.

β=2cos1((d2r21+r22)/2dr2)

α에 대해서도 반대로 똑같이 취해주면 됩니다.




반응형

'알고리즘 (Algorihtm) > 백준' 카테고리의 다른 글

boj 11014 - 컨닝 2  (0) 2024.01.11
boj 17435 - 합성함수와 쿼리  (0) 2023.12.25
boj 7626 - 직사각형  (2) 2021.12.29
boj 1069 - 집으로  (0) 2021.08.06
boj 17131 - 여우가 정보섬에 올라온 이유  (0) 2021.07.27
Comments