题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少。
思路 :先二分半径r,半平面交向内推进r。模板题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }