教官的监视
【题目描述】
有两个教官,每个教官有一个位置坐标和一个视线范围,该教官能够观察到以该位置为圆心,给定半径的一个圆,询问有多少面积的地方处在两个教官的视线范围内。
【输入描述】
第一行输入一个数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\n",P*(r1*r1+r2*r2)); else if (abs(r1-r2)>=D) //内含。 printf("%.3lf\n",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\n",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。 */