题目大意:给定一个多边形,问这个多边形内部距离多边形外部最远的点的距离是多少。。
思路:半平面交的题目,采用二分+半平面的判定
但是具体操作中就要涉及到直线的平移,需要注意一下。。
直接套模板
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 }