码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 3890 Most Distant Point from the Sea(二分法+半平面交)

时间:2016-02-02 08:39:13      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

 

题目链接: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 }

 

UVA 3890 Most Distant Point from the Sea(二分法+半平面交)

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5176694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!