The topic link: https://codeforces.com/problemset/problem/600/D
For the question, I'm wrong answer on test28, which could look like this:
correct answer:119256.95877838134765625000
my answer: 120502.639190673828125
I guess it is caused by calculation accuracy, but I don't have evidence. Maybe algorithm itself is faulty, please point it out.
Algorithm ideas:
For any given two circles, in order to simplify the calculation, we can translate the origin of the coordinates to the center of one of the circles, and then rotate the other circle to the x-axis by rotating. For calculating the intersection area of the circles, before and after are equivalent, and finally a purple circle and a red circle are formed. In fact, the final intersection area is equal to the sum of the areas of the two sectors minus the area of the diamond in the middle(the figure below, Horizontal axis x, vertical axis y). However, before that, we must first calculate the intersection point of the two circles.
The coordinates of the center of the first circle at the beginning:
.
The coordinates of the center of the second circle at the beginning:
.
The coordinates of the center of the first circle after a series of transformations:
.
The coordinates of the center of the second circle after a series of transformations:
,
.
The equations of two circles are combined:
are the radius of the first and second circles respectively,so:
we can use the sector area formula : ,
,
.
In this place, there will be problems with the positive and negative values of the radian(the two figures below), but it can be proved that they can be absorbed in the final result.
The final result is the sum of the areas of the two arcs minus the area of the middle diamond.
mycode:
# define MY_PI 3.14159265358979323846
using namespace std;
typedef long double ld;
ld pow2(ld x){return x * x;}
int main()
{
cout.precision(25);
ld x1, y1, r1, x2, y2, r2; // (x1, y1) is the center point of the circle, r1 is the radius of the circle, the other is similar.
cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
ld c = sqrt(pow2(x2 - x1) + pow2(y2 - y1));
if(r1 + r2 < c) // when r1+r2 < c, there is no intersection
{
cout << 0 << endl;
return 0;
}
if((max(r1, r2) - min(r1, r2)) >= c) // one circle is inside the other circle.
{
cout << MY_PI * pow2(min(r1, r2)) << endl;
return 0;
}
ld x = (pow2(r1) - pow2(r2)) / (2 * c) + c * 0.5;
ld y = sqrt(pow2(r1) - pow2(x));
ld angle1 = 2.0 * acos(x / r1);
ld angle2 = 2.0 * acos((c - x) / r2);
ld ar1 = angle1 * pow2(r1) * 0.5;
ld ar2 = angle2 * pow2(r2) * 0.5;
ld res = ar1 + ar2 - y * c;
cout << res << endl;
return 0;
}


