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 }

 

posted on 2013-04-12 00:04  yzcstc  阅读(269)  评论(0编辑  收藏  举报