题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11358
【思路】
二分法+半平面交
二分与海边的的距离,由法向量可以得到平移后的各边,半平面交在特定精度判断是否有交集。
【代码】
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const double eps = 1e-7; 8 9 struct Pt { 10 double x,y; 11 Pt(double x=0,double y=0):x(x),y(y) {} 12 }; 13 typedef Pt vec; 14 struct Line { 15 Pt P; vec v; 16 double ang; 17 Line () {}; 18 Line (Pt P,vec v):P(P),v(v) { ang=atan2(v.y , v.x); } 19 bool operator < (const Line& rhs) const{ 20 return ang<rhs.ang; 21 } 22 }; 23 24 vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); } 25 vec operator + (vec A,vec B) { return vec(A.x+B.x,A.y+B.y); } 26 vec operator * (vec A,double p) { return vec(A.x*p,A.y*p); } 27 double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y; } 28 double cross(Pt A,Pt B) { return A.x*B.y-A.y*B.x; } 29 double Len(vec A) { return sqrt(Dot(A,A)); } 30 vec Normal(vec A) { double L=Len(A); return vec(-A.y/L,A.x/L); } 31 32 bool onleft(Line L,Pt P) { return cross(L.v,P-L.P)>0; } 33 34 Pt LineIntersection(Line a,Line b) { 35 vec u=a.P-b.P; 36 double t=cross(b.v,u)/cross(a.v,b.v); 37 return a.P+a.v*t; 38 } 39 int HalfplaneIntersection(Line* L,int n,Pt* poly) { 40 sort(L,L+n); 41 int first,last; 42 Pt *p=new Pt[n]; 43 Line *q=new Line[n]; 44 q[first=last=0]=L[0]; 45 for(int i=1;i<n;i++) { 46 while(first<last && !onleft(L[i],p[last-1])) last--; 47 while(first<last && !onleft(L[i],p[first])) first++; 48 q[++last]=L[i]; 49 if(fabs(cross(q[last].v,q[last-1].v))<eps) { 50 last--; 51 if(onleft(q[last],L[i].P)) q[last]=L[i]; 52 } 53 if(first<last) p[last-1]=LineIntersection(q[last-1],q[last]); 54 } 55 while(first<last && !onleft(q[first],p[last-1])) last--; 56 if(last-first<=1) return 0; 57 p[last]=LineIntersection(q[last],q[first]); 58 int m=0; 59 for(int i=first;i<=last;i++) poly[m++]=p[i]; 60 return m; 61 } 62 63 const int N = 200+10; 64 Pt p[N],poly[N]; 65 Line L[N]; 66 vec v[N] , v2[N]; 67 int n; 68 69 int main() { 70 while(scanf("%d",&n)==1 && n) { 71 int m,x,y; 72 for(int i=0;i<n;i++) { 73 scanf("%d%d",&x,&y); 74 p[i]=Pt(x,y); 75 } 76 for(int i=0;i<n;i++) { 77 v[i]=p[(i+1)%n]-p[i]; 78 v2[i]=Normal(v[i]); 79 } 80 double left=0 , right=20000; 81 while(right-left>eps) { 82 double mid=left+(right-left)/2; 83 for(int i=0;i<n;i++) L[i]=Line(p[i]+v2[i]*mid,v[i]); 84 m=HalfplaneIntersection(L,n,poly); 85 if(!m) right=mid; else left=mid; 86 } 87 printf("%.6lf\n",left); 88 } 89 return 0; 90 }
时间: 2024-10-16 19:52:28