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

POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)

时间:2014-09-06 20:00:03      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   for   art   

题目链接

题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少。

思路 :先二分半径r,半平面交向内推进r。模板题

bubuko.com,布布扣
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <math.h>
  5 const double eps = 1e-10 ;
  6 
  7 using namespace std ;
  8 
  9 struct node
 10 {
 11     double x;
 12     double y ;
 13 } p[150],temp[150],newp[150];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
 14 int n,newn ;//原来的点数,切割后的点数
 15 double a,b,c ;//直线方程的三个系数
 16 
 17 void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
 18 {
 19     a = y.y-x.y ;
 20     b = x.x-y.x ;
 21     c = y.x*x.y - y.y*x.x ;
 22 }
 23 node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
 24 {
 25     double u = fabs(a*x.x+b*x.y+c) ;
 26     double v = fabs(a*y.x+b*y.y+c) ;
 27     node t ;
 28     t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
 29     t.y = (x.y*v+y.y*u)/(u+v) ;
 30     return t ;
 31 }
 32 void cut()
 33 {
 34     int cutn = 0 ;
 35     for(int i = 1 ; i <= newn ; i++)
 36     {
 37         if(a*newp[i].x+b*newp[i].y+c >= 0)//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
 38             temp[ ++cutn] = newp[i] ;
 39         else
 40         {
 41             if(a*newp[i-1].x+b*newp[i-1].y+c > 0)
 42                 temp[++cutn ] = intersect(newp[i-1],newp[i]) ;//把新交点加入
 43             if(a*newp[i+1].x+b*newp[i+1].y+c > 0)
 44                 temp[ ++cutn] = intersect(newp[i+1],newp[i]) ;
 45         }
 46     }
 47     for(int i = 1 ; i <= cutn ; i++)
 48         newp[i] = temp[i] ;
 49     newp[cutn+1] = temp[1] ;//能够找出所有点的前驱和后继
 50     newp[0] = temp[cutn] ;
 51     newn = cutn ;
 52 }
 53 double dist(double x,double y)
 54 {
 55     return sqrt(x*x+y*y) ;
 56 }
 57 bool solve(double r)
 58 {
 59     for(int i = 1 ; i <= n ; i++)
 60     {
 61         newp[i] = p[i] ;
 62     }
 63     p[n+1] = p[1] ;
 64     newp[n+1] = newp[1] ;
 65     newp[0] = newp[n] ;
 66     newn = n ;
 67     for(int i = 1 ; i <= n ; i++)
 68     {
 69         node t1,t2,t ;
 70         t.x = p[i+1].y-p[i].y ;
 71         t.y = p[i].x-p[i+1].x ;
 72         double k = r/dist(t.x,t.y) ;
 73         t.x *= k ;
 74         t.y *= k ;
 75         t1.x = t.x+p[i].x ;
 76         t1.y = t.y+p[i].y ;
 77         t2.x = t.x+p[i+1].x ;
 78         t2.y = t.y+p[i+1].y ;
 79         getline(t1,t2) ;//从头开始顺序遍历两个相邻点。
 80         cut() ;
 81     }
 82     if(newn == 0)
 83         return false ;
 84     else return true ;
 85 //求多边形核的面积
 86 //    double s = 0 ;
 87 //    for(int i = 1 ; i <= newn ; i++)
 88 //        s += newp[i].x*newp[i+1].y-newp[i].y*newp[i+1].x ;
 89 //    return s = fabs(s/2.0) ;
 90 }
 91 void guizhenghua()
 92 {
 93     for(int i = 1 ; i < (n+1)/2 ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
 94         swap(p[i],p[n-i]) ;
 95 }
 96 int main()
 97 {
 98     while(scanf("%d",&n)!=EOF && n)
 99     {
100         for(int i = 1 ; i <= n ; i++)
101             scanf("%lf %lf",&p[i].x,&p[i].y) ;
102         guizhenghua();
103         p[n+1] = p[1] ;
104         double high = 99999999 ,low = 0.0,mid ;
105         while(high-low >= eps)
106         {
107             mid = (low+high)/2.0 ;
108             if(solve(mid)) low = mid ;
109             else high = mid ;
110         }
111         printf("%lf\n",high) ;
112     }
113     return 0;
114 }
View Code

 

POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)

标签:style   blog   http   color   os   io   ar   for   art   

原文地址:http://www.cnblogs.com/luyingfeng/p/3959697.html

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