HDU 3264 求两圆相交的面积

来源:互联网 发布:手机淘宝怎么收藏店铺 编辑:程序博客网 时间:2024/05/22 05:09

此题意很简单,思路也容易想到。但是我就是卡在了求两圆相交求面积的地方。还好现在有了模板了。

不说了,直接贴代码,还得多多总结,二分真的很好用,要学会用啊!


#include<stdio.h>#include<iostream>#include<algorithm>#include<math.h>using namespace std;#define INF 2147483647#define N 25#define PI 3.141592653#define EPS 1e-8struct point{    double x;    double y;}p[N];double r[N];int n;double dis(point a,point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double interarea(point a,double ra,point b,double rb)   //求圆相交面积的模板 重点{    double ans=0;    double d=dis(a,b);    double temp;    if(ra<rb)    {        temp=ra;        ra=rb;        rb=temp;    }    if(d>=ra+rb)return 0;        //相离    if(d<=ra-rb)return PI*rb*rb;         //内含    double angle1=acos((ra*ra+d*d-rb*rb)/2.0/ra/d);    double angle2=acos((rb*rb+d*d-ra*ra)/2.0/rb/d);    ans-=d*ra*sin(angle1);    ans+=angle1*ra*ra+angle2*rb*rb;    return ans;}bool istrue(int t,double ra){    for(int i=0;i<n;i++)    {            double area=interarea(p[t],ra,p[i],r[i]);            if(area<0.5*PI*r[i]*r[i])return false;    }    return true;}double getr(int i){    double l,r,mid;    l=0;r=50000;    while(l+EPS<=r)    {        mid=(l+r)/2;        if(istrue(i,mid))r=mid-EPS;        else l=mid+EPS;    }    return mid;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)        {            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&r[i]);        }        double ans=INF;        for(int i=0;i<n;i++)        {            double radiu=getr(i);            if(ans>radiu)ans=radiu;        }        printf("%.4lf\n",ans);    }    return 0;}


原创粉丝点击