-
Source
思路:思路很直接就是写一个求两个圆相交面积的函数,然后ans=f(R,R,d)-2*f(r,R,d)+f(r,r,d) 即可(并不需要复杂的分类讨论)
这里有几点心得:
1. π的表示,不要写成3.1415926535,这样其实精度不够高,会WA! π要写成——pi=acos(-1.0)!!!
2. sgn,eps的使用,当用到浮点数比较大小的时候,由于存数精度的问题,应引入小量eps=1e-8,判断大于小于时用
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
return 1;
}
3. 调试程序时,输出-nan:表示not a number! 此时检查程序中是否有对负数进行开方,或者是否将0作为除数!
代码如下:
#include<cstdio>
#include<math.h>
#define eps 1e-8
#define pi acos(-1.0) //pi的值必须相当准确!
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
return 1;
}
double f(double r,double R,double d)
{
if(sgn(d-R-r)>=0) return 0.0;
if(sgn(R-r-d)>=0) return (pi*r*r);
double cos1=(R*R+d*d-r*r)/(2*R*d);
double cos2=(r*r+d*d-R*R)/(2*r*d);
double s1=acos(cos1)*R*R;
double s2=acos(cos2)*r*r;
double s3=sin(acos(cos1))*R*d;
return s1+s2-s3;
}
int main()
{
int T;
double R,r,x1,x2,y1,y2,d;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
scanf("%lf%lf%lf%lf%lf%lf",&r,&R,&x1,&y1,&x2,&y2);
d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
double ans=f(R,R,d)-2*f(r,R,d)+f(r,r,d);
printf("Case #%d: %.6lf\n",t,ans);
}
return 0;
}