教官的监视

【题目描述】

有两个教官,每个教官有一个位置坐标和一个视线范围,该教官能够观察到以该位置为圆心,给定半径的一个圆,询问有多少面积的地方处在两个教官的视线范围内。

【输入描述】

第一行输入一个数T,表示数据组数;

接下来T行,每行输入六个实数x1、y1、r1、x2、y2、r2,分别代表两个教官的各项参数。

【输出描述】

对于每组数据输出一个数,表示答案,答案保留三位小数。

【输入样例】

1

3 3 1 3 3 0.5

【输出样例】

3.142

【数据范围及提示】

对于10%的数据,两圆相离;

对于10%的数据,两圆内含;

对于40%的数据,T = 1,0 <= |x|,|y|,r <= 5;

对于100%的数据,T <= 10,0 <= |x|,|y| <= 105

源代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#define P 3.14159265358979323846264 //π的精度真是坑爹!
using namespace std;
int n;
int main() //math库的神威!acos()表示arc cos(),以弧度制返回,sin()等三角函数都包含于此。
{
    double x1,x2,y1,y2,r1,r2; //没想到y1还是个C++内置函数,所以只能main()内定义,爽到了。
    scanf("%d",&n);
    for (int a=0;a<n;a++)
    {
        scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&r1,&x2,&y2,&r2); //一般都是全程double类型。
        double D=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); //圆心距(曼哈顿距离)。
        if (r1+r2<=D) //相离。
          printf("%.3lf
",P*(r1*r1+r2*r2));
        else
          if (abs(r1-r2)>=D) //内含。
            printf("%.3lf
",P*(max(r1,r2)*max(r1,r2)));
          else //相交。
          {
            double ans=P*(r1*r1+r2*r2); //两圆分面积之和。
            double t1=acos((r1*r1+D*D-r2*r2)/(2*r1*D)); //一号圆内角。
            double t2=acos((r2*r2+D*D-r1*r1)/(2*r2*D)); //二号圆内角。
            ans-=r1*r1*t1+r2*r2*t2; //减去两个扇形。
            ans+=r1*D*sin(t1); //加上四边形(两个全等三角形)。
            printf("%.3lf
",ans);
          }
    }
    return 0;
}

/*
    一道普通数学题,画个图就能出来,可惜我已经把三角函数忘光光了。
    正弦定理:S=(a*b*sin(C))/2;
    余弦定理:cos(A)=(b*b+c*c-a*a)/(2*b*c);
    扇形面积:S=nπr^2/360。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/5932003.html