http://acm.hdu.edu.cn/showproblem.php?pid=5120
题意:
有两个相同的圆环,求其相交部分的面积,有T组输入数据,每个样例给出内圆半径r和外圆半径R,然后给出两个圆环的中心坐标。
输出case编号和相交部分面积,精确到小数点后六位。
思路:
圆环相交面积=两个大圆的交面积-2×大圆与小圆的交面积+两个小圆的交面积,
即主要求两个圆的交面积即可。
代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string> #include<iomanip> #include<algorithm> #include<string.h> #include<queue> #include<cmath> #include<stack> using namespace std; const int maxn = 5010; const int inf = 0x7f7f7f7f; typedef long long ll; struct point { double x,y; point(){} point(int _x,int _y):x(_x),y(_y){} point operator -(const point & a) const{ return point(x-a.x,y-a.y); } double operator *(const point &a)const{ return x*a.y-y*a.x; } double len(){ return sqrt(x*x+y*y); } }; struct circle { double r; point c; circle(){} circle(double _r,point _c):r(_r),c(_c){} }; double cl_inter(circle a,circle b) { if(a.r>b.r) swap(a,b); double r=a.r,R=b.r,d=(a.c-b.c).len(); if(d<=R-r) return acos(-1.0)*r*r; else if(d>=R+r) return 0; double x1=(d*d+r*r-R*R)/(2*d),x2=(d*d+R*R-r*r)/(2*d); double ans=(x1*sqrt(r*r-x1*x1)-r*r*acos(x1/r)); ans+=(x2*sqrt(R*R-x2*x2)-R*R*acos(x2/R)); return fabs(ans); } int main() { double r,R; point a,b; int T; scanf("%d",&T); for(int cas=1; cas<=T; cas++) { scanf("%lf%lf",&r,&R); scanf("%lf%lf",&a.x,&a.y); scanf("%lf%lf",&b.x,&b.y); double ans=cl_inter(circle(R,a),circle(R,b));//大圆交面积 ans-=2*cl_inter(circle(R,a),circle(r,b));//大圆与小圆交面积 ans+=cl_inter(circle(r,a),circle(r,b));//小圆交面积 printf("Case #%d: %.6lf ",cas,ans); } return 0; }