首页 > 代码库 > lightoj1118

lightoj1118

题意:判断两圆相交的面积有多大。

解题思路:1.两圆不相交,面积为0

              2.一个圆被另一个包含,面积为内圆面积

             3.一般情况下的相交,此时相交的面积与两圆圆心的位置无关,而只与两圆的位置有关。

设两圆的半径为r1,r2,两圆圆心之间的距离为d,那么可设两圆方程:x^2+y^2=r1^2,(x-d)^2+y^2=r2^2;

可得两圆相交处x=(r1^2-r2^2+d^2)/(2*d);然后我们可以分别得到相交处扇形角度的大小,由此可分别计算包含相交部分两圆中扇形的面积。两个扇形的面积减去,两半径组成的四边形的面积即为所求。

 1 //Accepted    1224 KB    0 ms
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 using namespace std;
 6 const double Pi=2*acos(0.0);
 7 double r1,r2,x1,x2,ty1,y2,d;
 8 double gets(double a,double b,double c)
 9 {
10     double p=(a+b+c)/2;
11     return sqrt(p*(p-a)*(p-b)*(p-c));
12 }
13 double slove()
14 {
15     d=sqrt((x1-x2)*(x1-x2)+(ty1-y2)*(ty1-y2));
16     if (d-r1-r2>=1e-9)
17     {
18         return 0.0;
19     }
20     if (d+r1-r2<=1e-9)
21     {
22         return Pi*r1*r1;
23     }
24     if (d+r2-r1<=1e-9)
25     {
26         return Pi*r2*r2;
27     }
28     double s=2*gets(r1,r2,d);
29     double t=(r1*r1-r2*r2+d*d)/(2*d);
30     double t2=d-t;
31     t=t/r1;
32     t2=t2/r2;
33     t=acos(t);
34     t2=acos(t2);
35     t=t*r1*r1;
36     t2=t2*r2*r2;
37     return t+t2-s;
38 }
39 int main()
40 {
41     int T;
42     int t;
43     scanf("%d",&T);
44     for (t=1;t<=T;t++)
45     {
46         scanf("%lf%lf%lf%lf%lf%lf",&x1,&ty1,&r1,&x2,&y2,&r2);
47         if (fabs(x1-x2)<1e-9 && fabs(ty1-y2)<1e-9)
48         {
49             printf("Case %d: %.9lf\n",t,Pi*r1*r1);
50             continue;
51         }
52         printf("Case %d: %.9lf\n",t,slove());
53     }
54     return 0;
55 }
View Code