poj3384
题目大意:给定一个多边形还有圆的半径R,求两个这样的圆最大能覆盖多大的面积(圆不能与边交叉),求出这样的两个圆心。。
思路:多边形的边向内推移半径R,再求半平面交。然后求交点的距离最大的两点。。输出
1 /* 2 Time:2013-04-11 19:02:48 3 State:Accepted 4 */ 5 #include<iostream> 6 #include<cstring> 7 #include<cstdio> 8 #include<cmath> 9 #include<algorithm> 10 #include<set> 11 #include<string> 12 #include<cstdlib> 13 #define eps 1e-9 14 #define maxn 210 15 using namespace std; 16 17 int ln, q[maxn], top, bot, n, ord[maxn], tot; 18 double maxdist, r; 19 struct point{double x, y; } p[maxn]; 20 struct line { 21 point a, b; 22 double angle; 23 } ; 24 line l[maxn], l1[maxn]; 25 26 void add_line(double x1, double y1, double x2, double y2 ){ 27 l1[ln].a.x = x1; 28 l1[ln].b.x = x2; 29 l1[ln].a.y = y1; 30 l1[ln].b.y = y2; 31 l1[ln].angle = atan2(y2 - y1, x2 - x1); 32 ord[ln] = ln; 33 ++ln; 34 } 35 36 void init(){ 37 double x1 , y1, x2, y2, dd; 38 // scanf("%lf", &r); 39 for (int i =0; i < n; ++i){ 40 scanf("%lf%lf",&x1, &y1); 41 p[i].x = x1; 42 p[i].y = y1; 43 } 44 ln = 0; 45 p[n] = p[0]; 46 for (int i = 0; i < n; ++i) 47 add_line(p[i + 1].x, p[i +1 ].y, p[i].x, p[i].y); 48 49 } 50 51 int dblcmp(double k){ 52 if (fabs(k) < eps) return 0; 53 return k > 0 ? 1 : -1; 54 } 55 56 double multi(point p0, point p1, point p2){ 57 return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); 58 } 59 60 bool cmp(const int u, const int v){ 61 int d = dblcmp(l[u].angle - l[v].angle); 62 if (d == 0) return dblcmp(multi(l[u].a, l[v].a,l[v].b)) > 0; 63 return d < 0; 64 } 65 66 void get_point(line l1, line l2, point& p){ 67 double dot1, dot2; 68 dot1 = multi(l2.a, l1.b, l1.a); 69 dot2 = multi(l1.b, l2.b, l1.a); 70 p.x = (l2.a.x * dot2 + l2.b.x * dot1) / (dot1 + dot2); 71 p.y = (l2.a.y * dot2 + l2.b.y * dot1) / (dot1 + dot2); 72 } 73 74 bool judge(line l0, line l1, line l2){ 75 point p; 76 get_point(l1, l2, p); 77 return dblcmp(multi(p, l0.a , l0.b)) < 0; 78 } 79 80 void nowline(double d){ 81 double datax, datay, dx, dy; 82 for (int i = 0; i < ln ;++i){ 83 dx = l1[i].b.x - l1[i].a.x; 84 dy = l1[i].b.y - l1[i].a.y; 85 datax = dy/ sqrt(dx*dx+dy*dy) * d; 86 datay = dx/ sqrt(dx*dx+dy*dy) * d; 87 l[i].a.x = l1[i].a.x - datax; 88 l[i].a.y = l1[i].a.y + datay; 89 l[i].b.x = l1[i].b.x - datax; 90 l[i].b.y = l1[i].b.y + datay; 91 l[i].angle = l1[i].angle; 92 ord[i] = i; 93 } 94 } 95 96 bool SAI(double mid){ 97 nowline(mid); 98 sort(ord, ord + ln , cmp); 99 int i, j; 100 for (i = 0, j = 0; i < ln; ++i) 101 if (dblcmp(l[ord[i]].angle - l[ord[j]].angle) > 0) 102 ord[++j] = ord[i]; 103 ln = j + 1; 104 q[0] = ord[0]; 105 q[1] = ord[1]; 106 bot = 0; 107 top = 1; 108 for (int i = 2; i < ln ; ++i){ 109 while (bot < top && judge(l[ord[i]], l[q[top - 1]], l[q[top]])) --top; 110 while (bot < top && judge(l[ord[i]], l[q[bot + 1]], l[q[bot]])) ++bot; 111 q[++top] = ord[i]; 112 } 113 while (bot < top && judge(l[q[bot]], l[q[top-1]], l[q[top]])) --top; 114 while (bot < top && judge(l[q[top]], l[q[bot+1]], l[q[bot]])) ++bot; 115 tot = 0; 116 q[++top] = q[bot]; 117 for (int i = bot; i < top; ++i){ 118 get_point(l[q[i]],l[q[i+1]], p[tot++]); 119 } 120 return 1; 121 122 } 123 124 125 void solve(){ 126 SAI(r); 127 double x1, y1, x2, y2, dist = -1.000, dd; 128 for (int i = 0; i < tot; ++i) 129 for (int j = i; j < tot; ++j){ 130 dd = sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); 131 if (dd > dist){ 132 dist = dd; 133 x1 = p[i].x; 134 y1 = p[i].y; 135 x2 = p[j].x; 136 y2 = p[j].y; 137 } 138 } 139 printf("%.4lf %.4lf %.4lf %.4lf\n",x1, y1, x2, y2); 140 141 } 142 143 int main(){ 144 freopen("poj3384.in","r",stdin); 145 freopen("poj3384.out","w",stdout); 146 while (scanf("%d%lf", &n, &r) != EOF){ 147 init(); 148 solve(); 149 } 150 fclose(stdin); fclose(stdout); 151 }