·模板题,求两环相交面积;
·有模板的情况下只需要考虑如何进行容斥即可。
我们画图进行解释:
对于如上两个圆环来说,首先我们将两个较大的圆分别定义为圆a和圆c;圆a中的小圆为圆b;圆c中的小圆为圆d。
那么对于这两个圆环来说,其相交面积,我们是要求1和4两部分。
第一部分:两大圆相交面积: 1+2+3+4+5
第二部分:圆a与圆d相交面积(一大一小):3 + 5
第三部分:圆b与圆c相交面积(一小一大):2 + 5
第四部分:两小圆相交面积:5
·那么结论就很明显:
两圆环相交面积 = 第一部分 - 第二部分 - 第三部分 + 第四部分
基础的容斥即可解决。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <cstring> 5 #include <string.h> 6 #include <math.h> 7 #include <queue> 8 #include <stack> 9 #include <stdlib.h> 10 #include <map> 11 using namespace std; 12 13 #define LL long long 14 #define sf(a) scanf("%d",&(a)); 15 #define inf 2e9 16 #define INF 2147483647 17 #define N 25 18 #define PI 3.141592653 19 #define EPS 1e-8 20 21 // 1009 数学模板题 22 // 大大 - 大小*2 + 小小 23 #include <cstdio> 24 #include <cstring> 25 #include <cmath> 26 #include <algorithm> 27 using namespace std; 28 const double eps = 1e-8; 29 const double pi = acos(-1.0); 30 struct Point { 31 double x, y; 32 Point operator - (const Point& t) const { 33 Point tmp; 34 tmp.x = x - t.x; 35 tmp.y = y - t.y; 36 return tmp; 37 } 38 Point operator + (const Point& t) const { 39 Point tmp; 40 tmp.x = x + t.x; 41 tmp.y = y + t.y; 42 return tmp; 43 } 44 bool operator == (const Point& t) const { 45 return fabs(x-t.x) < eps && fabs(y-t.y) < eps; 46 } 47 }GP; 48 49 double cir_area_inst(Point c1, double r1, Point c2, double r2) { // 两圆面积交 50 double a1, a2, d, ret; 51 d = sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y)); 52 if ( d > r1 + r2 - eps ) 53 return 0; 54 if ( d < r2 - r1 + eps ) 55 return pi*r1*r1; 56 if ( d < r1 - r2 + eps ) 57 return pi*r2*r2; 58 a1 = acos((r1*r1+d*d-r2*r2)/2/r1/d); 59 a2 = acos((r2*r2+d*d-r1*r1)/2/r2/d); 60 ret = (a1-0.5*sin(2*a1))*r1*r1 + (a2-0.5*sin(2*a2))*r2*r2; 61 return ret; 62 } 63 int main() 64 { 65 int T;int k=1; 66 scanf("%d",&T); 67 while(T--){ 68 Point a,b,c,d; 69 double r,R; 70 scanf("%lf%lf",&r,&R); 71 scanf("%lf%lf",&a.x,&a.y);b.x = a.x;b.y = a.y; 72 scanf("%lf%lf",&c.x,&c.y);d.x = c.x;d.y = c.y; 73 74 double area = cir_area_inst(a,R,c,R) - cir_area_inst(a,R,d,r)*2.0 + cir_area_inst(b,r,d,r); 75 printf("Case #%d: ",k++); 76 printf("%.6lf\n",area); 77 } 78 return 0; 79 80 }
时间: 2024-10-12 18:09:43