竟然花了一天的时间才过了这道几何题……
说下题意。给一个n边的凸多边形,保证给出的数据没有三点共线,求这个多边形能包含的最大圆的半径。
开始时完全搞错方向,甚至想了个把各个顶点的移动速度算出来的方法,结果发现根本行不通……正确的思路应该是二分半径,然后每次求一次半平面交判是否交集为空。其实乱搞速度的过程中想到了这个,但有点怀疑复杂度不够,SGU才给了0.25s的时限,复杂度还要nlogn乘一个感觉蛮大的常数……后来实在水不出来了就照这个思路敲了红书的模板,结果不知是敲错哪里来了个RTE……换了白书的模板才终于AC……
这A题的效率也是醉了……
#include<stdio.h>
#include<vector>
#include<deque>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<complex>
using namespace std;
const double eps=1e-8;
struct point
{
double x,y;
point(double xt=0,double yt=0):x(xt),y(yt) {}
};
double cross(point a,point b){return a.x*b.y-a.y*b.x;}
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 b) {return point(a.x*b,a.y*b);}
point operator /(point a,double b) {return point(a.x/b,a.y/b);}
struct line
{
point p,v;
double ang;
line(){}
line(point pt,point vt):p(pt),v(vt){ang=atan2(v.y,v.x);}
bool operator<(const line& l)const
{
return ang<l.ang;
}
};
bool onleft(line l,point p)
{
return cross(l.v,p-l.p)>0;
}
point getintersection(line a,line b)
{
point u=a.p-b.p;
double t=cross(b.v,u)/cross(a.v,b.v);
return a.p+a.v*t;
}
int halfplaneintersection(line *l,int n)
{
sort(l,l+n);
int first,last;
point *p=new point[n];
line *q=new line[n];
q[first=last=0]=l[0];
for(int i=1;i<n;i++)
{
while(first<last&&!onleft(l[i],p[last-1])) --last;
while(first<last&&!onleft(l[i],p[first])) ++first;
q[++last]=l[i];
if(fabs(cross(q[last].v,q[last-1].v))<eps)
{
last--;
if(onleft(q[last],l[i].p)) q[last]=l[i];
}
if(first<last) p[last-1]=getintersection(q[last-1],q[last]);
}
while(first<last&&!onleft(q[first],p[last-1])) --last;
if(last-first<=1) return 0;
p[last]=getintersection(q[last],q[first]);
return last-first+1;
}
double length(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
point normal(point a)
{
double le=length(a);
return point(-a.y/le,a.x/le);
}
int n;
point po[10005],nl[10005];
line lo[10005],lt[10005];
point re[10005];
int main()
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%lf %lf",&po[i].x,&po[i].y);
for(i=0;i<n;i++) {lo[i]=line(po[i],po[(i+1)%n]-po[i]);nl[i]=normal(po[(i+1)%n]-po[i]);}
double at=0,bt=2e7+10;
while(bt-at>1e-6)
{
double xt=(at+bt)/2;
for(i=0;i<n;i++) lt[i]=line(po[i]+nl[i]*xt,po[(i+1)%n]-po[i]);
int m=halfplaneintersection(lt,n);
if(m<=1) bt=xt;
else at=xt;
}
printf("%.5lf\n",(at+bt)/2);
return 0;
}