杭电 3264(相交圆求面积模板)

//就是找一个圆(圆心为给出的圆中的一个),满足覆盖其他所有的圆至少一般的面积
#include<stdio.h>
#include<math.h>
#define INF 100000000
#define EPS 1e-8  
#define PI 3.1415926
struct POINT
{
	double x,y,r;
}cir[30];

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 crossarea(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 j,double r)    // 判断j为圆心,半径为r是否满足条件
{
	for(int i=0;i<n;i++)
	{
		double area=crossarea(cir[j],r,cir[i],cir[i].r);
		if(area<0.5*PI*cir[i].r*cir[i].r)
			return false;
	}
	return true;
}
double getr(int i) 
{
	double left,right,mid;
	left=0;
	right=5000;
	
	while(left+EPS<=right)
	{
		mid=(left+right)/2;
		
		if(istrue(i,mid))  right=mid-EPS;
		else
			left=mid+EPS;
	}
	return mid;
}
int main()
{
	int i,t;
	scanf("%d",&t);
	
	while(t--)
	{
		scanf("%d",&n);
		
		for(i=0;i<n;i++)
			scanf("%lf%lf%lf",&cir[i].x,&cir[i].y,&cir[i].r);
        double ans=INF;
		
		for(i=0;i<n;i++)
        {
			double radio=getr(i);
			if(radio<ans)
				ans=radio;
			
			
		}

		printf("%.4lf\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值