题面
<center>Intersection<center>
<center>Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)<center>
Problem Description
Matt is a big fan of logo design. Recently he falls in love with logo made up by rings. The following figures are some famous examples you may know.
A ring is a 2-D figure bounded by two circles sharing the common center. The radius for these circles are denoted by r and R (r < R). For more details, refer to the gray part in the illustration below.
Matt just designed a new logo consisting of two rings with the same size in the 2-D plane. For his interests, Matt would like to know the area of the intersection of these two rings.
Input
The first line contains only one integer T (T ≤ 10^5^), which indicates the number of test cases. For each test case, the first line contains two integers r, R (0 ≤ r < R ≤ 10).
Each of the following two lines contains two integersx$_i$, y$_i$ (0 ≤ x$_i$, y$_i$ ≤ 20) indicating the coordinates of the center of each ring.
Output
For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y is the area of intersection rounded to 6 decimal places.
Sample Input
2
2 3
0 0
0 0
2 3
0 0
5 0
Sample Output
Case #1: 15.707963
Case #2: 2.250778
思路
题解
比较简单的一道题,但是我们却卡了好久……;最主要的问题是pi的精度问题;我们一开始调用库里的M_PI,但是在本地没问题,在平台上却编译错误……,我们就把pi 重定义为:3.1415926535,没想到精度不够,wa了好多次……还浪费了大量时间。正确pi:acos(-1.0)。
这题还是比较简单的,求两个圆环重叠部分的面积,可以转化为ans=s3-2*s2+s1;
其中:将圆环看成由大圆&小圆组成;s1:两个小圆围成面积,s2:小圆与大圆围成面积,s3:两个大圆围成面积;画图即可利用三角定理求解面积。
源码
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#define M_PI acos(-1.0)
using namespace std;
typedef struct{
int x,y;
}point;
double fun(point p1,point p2,int r1,int r2){
//计算以点p1为圆心,以r1为半径的圆和以点p2为圆心,以r2为半径的圆围成的面积
double d=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
if(d>=r1+r2) return 0;
double r;r=r1<r2?r1:r2;
//if(d<=fabs(r1-r2)) return M_PI*r*r;
if(d<=abs(r1-r2)) return M_PI*r*r;
double s1,s2;
//double j1,j2;
//j1=acos((r1*r1+(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)-r2*r2)/(2*r1*d));
s1=acos((r1*r1+(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)-r2*r2)/(2*r1*d))*r1*r1;
//j2=acos((r2*r2+(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)-r1*r1)/(2*r2*d));
s2=acos((r2*r2+(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)-r1*r1)/(2*r2*d))*r2*r2;
double s4=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))*r1*sin(acos((r1*r1+(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)-r2*r2)/(2*r1*d)));
//s4=d2*d;
//printf("s1:%.6f\ns2:%.6f\ns4:%.6f\n",s1,s2,s4);
return s1+s2-s4;
}
int main() {
int i,T;scanf("%d",&T);
for(i=1;i<=T;i++){
point p1,p2;
int r1,r2;
double s1,s2,s3,ans,s22;
scanf("%d%d%d%d%d%d",&r1,&r2,&p1.x,&p1.y,&p2.x,&p2.y);
//srand(time());
//r1=rand()%11;r2=rand()%11;
//p1.x=rand()%21;p1.y=rand()%21;p2.x=rand()%21;p2.y=rand()%21;
s1=fun(p1,p2,r1,r1);//小圆1与小圆2
s2=fun(p1,p2,r1,r2);//小圆1与大圆2
s3=fun(p1,p2,r2,r2);//大圆1与大圆2
ans=s3-2*s2+s1;
//if(s2==s22) printf("Yes\n");
//else {printf("No\n,s2:%lf,s22:%lf\n",s2,s22);}
printf("Case #%d: %.6lf\n",i,ans);
}
return 0;
}
/*
2
2 3
0 0
0 0
2 3
0 0
5 0
*/