https://vjudge.net/problem/UVALive-3890
题意:凸n边形小岛,求岛上距海的最远的一点距海的最短距离(凸包内切圆半径)
二分+半平面交判断是否存在这样的点
#include<cmath> #include<cstdio> #include<algorithm> #define N 101 using namespace std; const double eps=1e-6; struct Point { double x,y; Point (double x=0,double y=0) : x(x),y(y) { } }; typedef Point Vector; Point P[N],Poly[N]; Vector v[N],v2[N]; Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); } Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operator * (Vector A,double b) { return Vector(A.x*b,A.y*b); } struct Line { Point P; Vector v; double ang; Line() {} Line(Point P,Vector v) : P(P),v(v) { ang=atan2(v.y,v.x); } bool operator < (Line L) const { return ang<L.ang; } }; Line L[N]; double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; } double Dot(Vector A,Vector B) { return A.x*B.x+A.y*B.y; } double Length(Vector A) { return sqrt(Dot(A,A)); } Vector Normal(Vector A) { double L=Length(A); return Vector(-A.y/L,A.x/L); } bool OnLeft(Line L,Point p) { return Cross(L.v,p-L.P)>0; } Point GetIntersection(Line a,Line b) { Vector u=a.P-b.P; double t=Cross(b.v,u)/Cross(a.v,b.v); return a.P+a.v*t; } bool 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--; return last-first>1; } int main() { int n,m; int x,y; double l,r,mid; while(scanf("%d",&n)!=EOF) { if(!n) return 0; for(int i=0;i<n;++i) { scanf("%d%d",&x,&y); P[i]=Point(x,y); } for(int i=0;i<n;++i) { v[i]=P[(i+1)%n]-P[i]; v2[i]=Normal(v[i]); } l=0; r=20000; while(r-l>eps) { mid=(l+r)/2; for(int i=0;i<n;++i) L[i]=Line(P[i]+v2[i]*mid,v[i]); if(HalfplaneIntersection(L,n)) l=mid; else r=mid; } printf("%.6lf ",l); } }