`
java-mans
  • 浏览: 11384452 次
文章分类
社区版块
存档分类
最新评论

hdu 3264Open-air shopping malls 两圆求交+二分

 
阅读更多

在排除商店的中心不在雨伞范围内,排除伞在商店内而面积达不到一半时。

面雨伞覆盖了整个商店是可行的,最后剩一种相交的情况,求圆面积的并。

//之前不怎么敢用三角函数怕丢失精度,没想是可以的。

代码如下 :

#include<iostream>
#include<cstdio>
#include<math.h>
#define eps 1e-8
#define inf 1e8
#define maxn 100
#define PI acos(-1.0)

struct point {double x,y;};
struct circle{point cen;double r;}cir[maxn];
int id;double minr;
int n;
bool zero(double x){return x>0? x<eps :x>-eps;}
double min(double a,double b){return a>b? b:a;}
double distance(point p1,point p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
bool judge(double rr)
{
	int i;
	for(i=0;i<n;i++)
	{
		double dis=distance(cir[id].cen,cir[i].cen);
		if(rr-dis< eps)return false;//
		if(rr-dis-cir[i].r>=0)continue;//c?úo?,?ú?Da
		double a=cir[i].r*cir[i].r*PI;
		double c=rr*rr*PI;
		if(dis+rr-cir[i].r<-eps)//a?úo?c
		{
			if(c-a/2> -eps)continue;
			else return false;
		}
		double l=(rr+dis+cir[i].r)/2;
		double area1=2*sqrt(l*(l-rr)*(l-dis)*(l-cir[i].r));
		double anga=acos((cir[i].r*cir[i].r+dis*dis-rr*rr)/(2*dis*cir[i].r));
		double angc=acos((dis*dis+rr*rr-cir[i].r*cir[i].r)/(2*dis*rr));
		double res=anga/(PI)*a+angc/(PI)*c-area1;
		if(res-a/2<0)return false;
	}
	return true;
}
double two(double l,double r)
{
	double mid=(l+r)/2.0;
	if(zero(r-l))return mid;
	if(judge(mid))
		return two(l,mid);
	else return two(mid,r);
}
int main()
{
	int t ;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		int i;
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&cir[i].cen.x,&cir[i].cen.y,&cir[i].r);
		}
		double minn=inf;
		for(i=0;i<n;i++)
		{
			id=i;
			minn=min(minn,two(0,inf));
		}
		printf("%.4lf\n",minn);
	}
	return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics