poj3525

题目大意:给定一个多边形,问这个多边形内部距离多边形外部最远的点的距离是多少。。

思路:半平面交的题目,采用二分+半平面的判定

        但是具体操作中就要涉及到直线的平移,需要注意一下。。

        直接套模板

code:

   

  1 /*
  2    State:Accepted
  3    Time:2013-04-11 19:04:00
  4 */
  5 
  6 #include<iostream>
  7 #include<cstring>
  8 #include<string>
  9 #include<fstream>
 10 #include<algorithm>
 11 #include<set>
 12 #include<cmath>
 13 using namespace std;
 14 const int maxn = 200;
 15 const double eps = 1e-8;
 16 
 17 struct point{ double x, y; };
 18 struct line{
 19        point a,b;
 20        double angle;
 21 };
 22 
 23 int n, ln , ord[maxn], q[maxn];
 24 line l[maxn];
 25 
 26 void add_line(double x1, double y1, double x2, double  y2){
 27      l[ln].a.x = x1;
 28      l[ln].a.y = y1;
 29      l[ln].b.x = x2;
 30      l[ln].b.y = y2;
 31      ord[ln] = ln; 
 32      ln++;    
 33 }
 34 
 35 void init(){
 36      double x1,  x2, y1 ,y2;
 37      for (int i = ln = 0; i < n; ++i){
 38           scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 
 39           add_line(x1, y1, x2, y2);   
 40      }
 41      add_line(0,0,40000,0);
 42      add_line(40000,0,40000,40000);
 43      add_line(40000,40000,0,40000);
 44      add_line(0,40000,0,0);
 45 }
 46 
 47 double multi(point p0, point p1, point p2){
 48     return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);    
 49 }
 50 
 51 bool dblcmp(double v){
 52      if (fabs(v) < eps) return 0;
 53      return v > 0 ? 1 : 0;
 54 }
 55 
 56 bool cmp(const int u, const int v){
 57      int d = dblcmp(l[v].angle - l[u].angle);
 58      if (d == 0) return dblcmp(multi(l[u].a, l[u].b, l[v].b)) < 0;
 59      return d > 0;
 60 }
 61 
 62 void  get_point(line l1, line l2, point &p){
 63      double dot1 = multi(l1.a, l2.a, l1.b);
 64      double dot2 = multi(l1.a, l1.b, l2.b);
 65      p.x = (l2.a.x*dot2 + l2.b.x*dot1) / (dot1 + dot2);
 66      p.y = (l2.a.y*dot2 + l2.b.y*dot1) / (dot1 + dot2);
 67 }
 68 
 69 bool judge(line l0, line l1, line l2){
 70      point  p;
 71      get_point(l1, l2, p);
 72      return dblcmp(multi(l0.a, l0.b, p)) < 0;
 73 }
 74 
 75 bool SAI(double mid){
 76      sort(ord, ord + ln, cmp);  
 77      int tot = 0;  
 78      for (int i = 1;  i < ln;  ++i)
 79        if (dblcmp(l[ord[i]].angle - l[ord[tot]].angle) > 0)
 80            ord[++tot] = ord[i];
 81      ln = ++tot;
 82      int bot = 0, top = 1;
 83      q[1] = ord[1];
 84      q[2] = ord[2];
 85      for (int i = 2; i < ln; ++i){
 86           while (bot < top && judge(l[ord[i]], l[ord[top-1]], l[ord[top]])) --top;
 87           while (bot < top && judge(l[ord[i]], l[ord[bot+1]], l[ord[bot]])) ++bot;
 88           q[++top] = ord[i];
 89      }
 90      while (bot < top && judge(l[q[bot]], l[q[top-1]], l[q[top]])) --top; 
 91      while (bot < top && judge(l[q[top]], l[q[bot + 1]], l[q[bot]])) ++bot;  
 92      if (top - bot > 2) return true;
 93      else return false;
 94      
 95 }
 96 
 97 void solve(){
 98     double l = 0.0, r = 40000.0, mid ;
 99     while  (r - l < 1e-7){
100          mid = (l + r)/2;
101          if (SAI(mid)) r = mid;
102          else r = mid;
103     }      
104     printf("%.5f\n",l); 
105 }
106 
107 int main(){
108      freopen("poj3525.in", "r", stdin);
109      freopen("poj3525.out","w",stdout);   
110      while (scanf("%d", &n) != EOF && n){
111           init();
112           solve();  
113      }
114      fclose(stdin); fclose(stdout);
115 }

 

posted on 2013-04-11 23:49  yzcstc  阅读(167)  评论(0编辑  收藏  举报