Intersection(计算几何)
Intersection
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 3018 Accepted Submission(s): 1135
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 ≤ 105), 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 integers xi, yi (0 ≤ xi, yi ≤ 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
Sample Output
Source
2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交)
//题意:问两个同样大的圆环相交的面积是多大
画图后,可以发现,用容斥定理很简单,area = 两个大圆的相交面积 - 2 * 大圆和小圆相交面积 + 两个小圆相交面积
求面积要用余弦定理,然后就简单了
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <math.h> 6 #include <algorithm> 7 #include <map> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <vector> 12 using namespace std; 13 #define LL long long 14 #define PI acos(-1.0) 15 #define lowbit(x) (x&(-x)) 16 #define INF 0x7f7f7f7f // 21 E 17 #define MEM 0x7f // memset 都变为 INF 18 #define MOD 4999 // 模 19 #define eps 1e-9 // 精度 20 #define MX 1000005 // 数据范围 21 22 int read() { //输入外挂 23 int res = 0, flag = 0; 24 char ch; 25 if((ch = getchar()) == '-') flag = 1; 26 else if(ch >= '0' && ch <= '9') res = ch - '0'; 27 while((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch - '0'); 28 return flag ? -res : res; 29 } 30 // code... ... 31 32 double area(double x1,double y1,double r1,double x2,double y2,double r2) 33 { 34 double d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); 35 if(d>=(r1+r2)*(r1+r2)) return 0; 36 if(d<=(r1-r2)*(r1-r2)) return r1<r2 ? PI*r1*r1 : PI*r2*r2; 37 d=sqrt(d); 38 double a1=acos((r1*r1+d*d-r2*r2)/(2.0*r1*d)); 39 double a2=acos((r2*r2+d*d-r1*r1)/(2.0*r2*d)); 40 double s1=a1*r1*r1; //扇形s1 41 double s2=a2*r2*r2; 42 double sinx = sqrt(1-cos(a1)*cos(a1)); 43 double t = sinx * d * r1; //三角形 44 return s1+s2-t; 45 } 46 47 int main() 48 { 49 int T; 50 cin>>T; 51 for (int cnt=1;cnt<=T;cnt++) 52 { 53 double x1,y1,x2,y2,r1,r2; 54 scanf("%lf%lf",&r1,&r2); 55 scanf("%lf%lf",&x1,&y1); 56 scanf("%lf%lf",&x2,&y2); 57 double ans = area(x1,y1,r2,x2,y2,r2); 58 ans -= 2*area(x1,y1,r1,x2,y2,r2); 59 ans += area(x1,y1,r1,x2,y2,r1); 60 printf("Case #%d: %.6f\n",cnt,ans); 61 } 62 }