HDU

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.

InputThe 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 integers x i, y i (0 ≤ x i, y i ≤ 20) indicating the coordinates of the center of each ring.OutputFor 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

这题本是水题,无奈我思维太僵硬。愣是问了人家才ac。发现自己不会总结归纳,很多规律我明明已经找到了,但就是没法总结成一个式子,得练啊。
题意:给两个环,求其相交面积。
解题思路:可以轻易推出一般情况下的公式是ans=areaRR-2*arearR+arearr。在其他情况下,其实也一样,只不过有的area为0了而已,只需要把这两个环变成两种圆R和r相交情况就行了。具体看代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <iomanip>
 6 #include <cmath>
 7 using namespace std;
 8 typedef long long ll;
 9 const int maxn = 1e6+10;
10 int nu[maxn],cnt,minn;
11 const double pi = acos(-1.0);
12 const double eps = 1e-6;
13 inline double getd(double xa,double ya,double xb,double yb)
14 {
15     return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
16 }
17 double getarea(double xa,double ya,double xb,double yb,double r,double R)
18 {
19     double d=getd(xa,ya,xb,yb);
20    // cout<<d<<"d"<<endl;
21     if(d+eps>r+R) return 0; //不相交
22     if(d<R-r+eps)//圆R与圆r无相交面积
23     {
24         return pi*r*r;
25     }
26     double cosa=(R*R+d*d-r*r)/(2*R*d);
27   //  cout<<cosa<<endl;
28     double c=R*cosa;
29    // cout<<c<<endl;
30     double anga=acos(cosa);
31     double e=d-c;
32     double angb=acos(e/r);
33     return R*R*anga+r*r*angb-d*R*sin(anga);
34 }
35 
36 int main()
37 {
38     cout<<setiosflags(ios::fixed)<<setprecision(6);
39     int t;
40     double rr,RR,xa,ya,xb,yb,r,R;
41     scanf("%d",&t);
42     for(int cas=1;cas<=t;++cas)
43     {
44         cout<<"Case #"<<cas<<": ";
45         cin>>rr>>RR;
46         r=min(rr,RR);
47         R=max(RR,rr);
48         cin>>xa>>ya>>xb>>yb;
49         double ans=getarea(xa,ya,xb,yb,R,R)-2.0*getarea(xa,ya,xb,yb,r,R)+getarea(xa,ya,xb,yb,r,r);
50         cout<<setprecision(6)<<ans<<endl;
51     }
52     return 0;
53 }
View Code
原文地址:https://www.cnblogs.com/zmin/p/8358947.html