标签:codeforces 二分答案 计算几何
题目大意:给定平面上的三个点
设
首先如果
否则两人分离时
容易发现答案是单调的,我们不妨二分答案
不妨设分离点为
容易发现每个不等式中
因此我们只需要判断三个圆是否有公共部分即可
具体怎么做自己玩去吧 注意精度
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define EPS 1e-15
#define PI 3.1415926535897932
using namespace std;
typedef long double ld;
struct Point{
ld x,y;
Point() {}
Point(ld _,ld __):
x(_),y(__) {}
friend istream& operator >> (istream &_,Point &p)
{
return _>>p.x>>p.y;
}
friend Point operator + (const Point &p1,const Point &p2)
{
return Point(p1.x+p2.x,p1.y+p2.y);
}
friend Point operator - (const Point &p1,const Point &p2)
{
return Point(p1.x-p2.x,p1.y-p2.y);
}
friend ld Distance(const Point &p1,const Point &p2)
{
return sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
}
friend ld Arctan2(const Point &p)
{
return atan2(p.y,p.x);
}
}A,B,C;
struct Interval{
ld l,r;
Interval() {}
Interval(ld _,ld __):
l(_),r(__) {}
bool In_Interval(ld x) const
{
return x>=l && x<=r ;
}
friend bool Intersect(const Interval &i1,const Interval &i2)
{
return i1.In_Interval(i2.l) || i1.In_Interval(i2.r) || i2.In_Interval(i1.l) ;
}
};
struct Circle{
Point o;
ld r;
Circle() {}
Circle(const Point &_,const ld &__):
o(_),r(__) {}
friend bool Seperated(const Circle &c1,const Circle &c2)
{
return Distance(c1.o,c2.o) > c1.r + c2.r + EPS ;
}
friend bool Include(const Circle &c1,const Circle &c2)
{
return Distance(c1.o,c2.o) < fabs(c1.r-c2.r) ;
}
friend Interval Get_Intersection(const Circle &c1,const Circle &c2)
{
ld alpha=Arctan2(c2.o-c1.o);
ld a=c1.r;
ld b=Distance(c1.o,c2.o)-EPS;
ld c=c2.r;
ld delta=acos( (a*a+b*b-c*c)/(2*a*b) );
return Interval(alpha-delta,alpha+delta);
}
};
ld t1,t2;
bool Check(const Circle &c1,const Circle &c2,const Circle &c3)
{
Interval i1=Get_Intersection(c1,c2);
Interval i2=Get_Intersection(c1,c3);
if( Intersect(i1,i2) )
return true;
i1.l+=2*PI;i1.r+=2*PI;
if( Intersect(i1,i2) )
return true;
i1.l-=4*PI;i1.r-=4*PI;
if( Intersect(i1,i2) )
return true;
return false;
}
bool Judge(ld mid)
{
Circle c1(A,mid);
Circle c2(B,t1-mid);
Circle c3(C,t2-Distance(B,C)-mid);
if( Seperated(c1,c2) || Seperated(c1,c3) || Seperated(c2,c3) )
return false;
if( Include(c1,c2) || Include(c1,c3) || Include(c2,c3) )
return true;
return Check(c1,c2,c3) || Check(c2,c1,c3) || Check(c3,c1,c2) ;
}
ld Bisection()
{
ld l=0,r=min(t1,t2-Distance(B,C));
while(r-l>EPS)
{
ld mid=(l+r)/2;
if(Judge(mid))
l=mid;
else
r=mid;
}
return (l+r)/2;
}
int main()
{
cin>>t2>>t1>>A>>B>>C;
t1+=Distance(A,B);
t2+=Distance(A,C);
t2+=Distance(B,C);
if( t1>=Distance(A,C)+Distance(B,C) )
return cout<<fixed<<setprecision(10)<<min(t1,t2)<<endl,0;
cout<<fixed<<setprecision(10)<<Bisection()<<endl;
return 0;
}
codeforces #8D Two Friends 二分答案+计算几何
标签:codeforces 二分答案 计算几何
原文地址:http://blog.csdn.net/popoqqq/article/details/45719007