1 2 0 0 1 2 0 1
2.0822
求一个最小半径使得圆心位于 某一个圆的圆心时,可以覆盖n个圆中每一个圆的至少一半面积。
二分半径,然后枚举圆心,判断可行性。
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/4/20 9:39:31
File Name :8.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pi acos(-1.0)
typedef long long ll;
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x>0?1:-1;
}
struct Point{
double x,y;
Point(double _x=0,double _y=0){
x=_x;y=_y;
}
};
Point operator + (Point a,Point b){
return Point(a.x+b.x,a.y+b.y);
}
Point operator - (Point a,Point b){
return Point(a.x-b.x,a.y-b.y);
}
Point operator * (Point a,double p){
return Point(a.x*p,a.y*p);
}
Point operator / (Point a,double p){
return Point(a.x/p,a.y/p);
}
bool operator < (const Point &a,const Point &b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
bool operator == (const Point &a,const Point &b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Point a,Point b){
return a.x*b.x+a.y*b.y;
}
double Length(Point a){
return sqrt(Dot(a,a));
}
double Angle(Point a,Point b){
return acos(Dot(a,b)/Length(a)/Length(b));
}
double angle(Point a){
return atan2(a.y,a.x);
}
double Cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
Point vecunit(Point x){
return x/Length(x);
}
Point Normal(Point x){
return Point(-x.y,x.x);
}
Point Rotate(Point a,double rad){
return Point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
struct Line{
Point p,v;
double ang;
Line(){}
Line(Point P,Point v):p(P),v(v){
ang=atan2(v.y,v.x);
}
bool operator < (const Line &L) const {
return ang<L.ang;
}
Point point(double a){
return p+(v*a);
}
};
bool SegmentIntersection(Point a1,Point a2,Point b1,Point b2){
double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r){}
Point point(double a){
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
double area_cir_cir(Circle a,Circle b){
double d=Length(a.c-b.c),r1=a.r,r2=b.r,r;
if(r1+r2<=d)return 0;
else if(fabs(r1-r2)>=d){
r=min(r1,r2);
return pi*r*r;
}
else{
double a1=(r1*r1+d*d-r2*r2)/(2*r1*d);
double a2=(r2*r2+d*d-r1*r1)/(2*r2*d);
a1=2*acos(a1);
a2=2*acos(a2);
return (r1*r1*(a1-sin(a1))+r2*r2*(a2-sin(a2)))/2;
}
}
Circle s[100];
int main()
{
int T,n;
cin>>T;
while(T--){
cin>>n;
for(int i=0;i<n;i++)cin>>s[i].c.x>>s[i].c.y>>s[i].r;
double left=0,right=100000;
while(left+eps<right){
double mid=(left+right)/2;
int flag=0;
for(int i=0;i<n;i++){
int flag1=1;
Circle p;p.c=s[i].c;p.r=mid;
for(int j=0;j<n;j++){
double s1=area_cir_cir(p,s[j]);
if(s1<pi*s[j].r*s[j].r/2){
flag1=0;break;
}
}
if(flag1){
flag=1;break;
}
}
// cout<<"han "<<left<<" "<<right<<" "<<mid<<endl;
if(!flag)left=mid;
else right=mid;
}
printf("%.4lf\n",left);
}
}
HDU 3264 两圆相交,枚举+二分,布布扣,bubuko.com
原文:http://blog.csdn.net/xianxingwuguan1/article/details/24304175