[백준 7869] 두 원 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
두 원의 중심 좌표와 반지름이 주어질 때, 두 원이 겹치는 부분의 넓이를 구하는 문제입니다.
접근법
두 원의 중심 사이 거리에 따라 세 가지 경우로 나뉩니다.
먼저, 두 원이 완전히 분리된 경우입니다. 중심 거리가 두 반지름의 합 이상이면 겹치는 부분이 없으므로 넓이는 0입니다.
다음으로, 한 원이 다른 원에 완전히 포함된 경우입니다. 중심 거리에 작은 반지름을 더한 값이 큰 반지름 이하이면, 작은 원 전체가 큰 원 안에 들어갑니다. 이때 겹치는 넓이는 작은 원의 넓이입니다.
마지막으로, 두 원이 부분적으로 겹치는 경우입니다. 코사인 법칙으로 각 원에서 교차 부분이 차지하는 각도를 구합니다. 각 원에서 부채꼴 넓이를 구한 뒤, 겹치는 삼각형 부분을 빼면 렌즈 모양의 교차 넓이가 됩니다.
Code
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
class Program {
static void Main() {
var s = Console.ReadLine()!.Split();
var x1 = double.Parse(s[0]);
var y1 = double.Parse(s[1]);
var r1 = double.Parse(s[2]);
var x2 = double.Parse(s[3]);
var y2 = double.Parse(s[4]);
var r2 = double.Parse(s[5]);
if (r1 < r2) { (r1, r2) = (r2, r1); (x1, x2) = (x2, x1); (y1, y2) = (y2, y1); }
var dx = x1 - x2;
var dy = y1 - y2;
var d = Math.Sqrt(dx * dx + dy * dy);
var area = 0.0;
if (d >= r1 + r2) area = 0.0;
else if (d + r2 <= r1) area = Math.PI * r2 * r2;
else {
var t1 = Math.Acos((d * d + r1 * r1 - r2 * r2) / (2 * d * r1));
var t2 = Math.Acos((d * d + r2 * r2 - r1 * r1) / (2 * d * r2));
var lens = r1 * r1 * t1 + r2 * r2 * t2;
var tri = 0.5 * Math.Sqrt(Math.Max(0.0, (-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2)));
area = lens - tri;
}
Console.WriteLine(area.ToString("0.000"));
}
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
double x1, y1, r1, x2, y2, r2;
cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
if (r1 < r2) { swap(r1, r2); swap(x1, x2); swap(y1, y2); }
double dx = x1 - x2, dy = y1 - y2;
double d = sqrt(dx*dx + dy*dy);
double area;
if (d >= r1 + r2) area = 0.0;
else if (d + r2 <= r1) area = M_PI * r2 * r2;
else {
double t1 = acos((d*d + r1*r1 - r2*r2) / (2 * d * r1));
double t2 = acos((d*d + r2*r2 - r1*r1) / (2 * d * r2));
double lens = r1*r1 * t1 + r2*r2 * t2;
double tri = 0.5 * sqrt(max(0.0, (-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2)));
area = lens - tri;
}
cout.setf(ios::fixed);
cout.precision(3);
cout << area << "\n";
return 0;
}