跳转至

CF600D

知识点

  • 计算几何
  • 余弦定理

题意简述

求两个圆的交的面积1

数据范围:\(-10^9 \le x_1, y_1, x_2, y_2 \le 10^9\)\(1 \le r_1, r_2 \le 10^9\)

解题思路

用余弦定理解三角形即可,然后用 \(S = \dfrac{1}{2}ab\sin C\) 来求三角形面积,\(S = \dfrac{1}{2}\alpha r^2\) 来求扇形面积,相减即可得到答案。

卡精度。

代码实现

核心部分已用高亮标出。

Code
 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
33
34
35
36
37
#include <bits/stdc++.h>
#define LD long double

const LD PI = std::acos(-1);

LD ra, rb;

struct POINT {
    LD x, y;
} A, B;

LD dist(POINT a, POINT b) {
    return std::sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

LD solve(LD a, LD b, LD c) {
    LD cosC = (a * a + b * b - c * c)/(2 * a * b);
    LD angC = std::acos(cosC) * 2;
    LD sin2C = std::sin(ang2C);
    return a * a * ang2C / 2 - a * a * sin2C / 2;
}

int32_t main() {
    std::cin >> A.x >> A.y >> ra;
    std::cin >> B.x >> B.y >> rb;
    if(ra > rb)
        std::swap(A, B), std::swap(ra, rb);
    LD dis = dist(A, B);
    if(dis >= ra + rb)
        printf("0");
    else if(dis + ra <= rb)
        printf("%.20f", (double)(PI * ra * ra));
    else
        printf("%.20f", (double)(solve(ra, dis, rb) + solve(rb, dis, ra)));

    return 0;
}