Intersection

题面

<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
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值