题目大意:

给定一个多边形,给定一个圆的半径,要求在多边形中放置两个同样半径的圆,可相互覆盖,但不能超出多边形的范围,希望两个圆的面积覆盖和最大

输出任意一组满足的圆的圆心点

 

如果两个圆不相互覆盖,那么必然达到最大面积

如果相互覆盖,可以换一种方式考虑,因为两个圆是一样的,两个圆的距离越长,那么相互覆盖的面积必然越小

所以可以将多边形内推进半径的长度

然后在半平面交后得到的多边形中找到距离最远的两个点

仔细想一想可以知道多边形上最远距离的点,必然是两个顶点的距离

所以平方的方法就可以求解了

当然用旋转卡壳的话在n的复杂度内就可以完美解决也是可行的

这里就用第一种简单的方法了

这里感觉精度卡的比较严,之前没写dcmp就一直过不了,尝试着加了一些精确度判断就a了

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 #define N 105
  8 #define eps 1e-9
  9 
 10 int dcmp(double x)
 11 {
 12     if(fabs(x)<eps) return 0;
 13     return x<0?-1:1;
 14 }
 15 
 16 struct Point{
 17     double x , y;
 18     Point(double x=0 , double y=0):x(x),y(y){}
 19     void input(){scanf("%lf%lf" , &x , &y);}
 20     double dis(Point m){
 21         return (x-m.x)*(x-m.x)+(y-m.y)*(y-m.y);
 22     }
 23 }p[N] , poly[N];
 24 
 25 typedef Point Vector;
 26 
 27 struct Line{
 28     Point p;
 29     Vector v;
 30     double ang;
 31     Line(){}
 32     Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
 33     bool operator<(const Line &m) const{
 34         return dcmp(ang-m.ang)<0;
 35     }
 36 }line[N];
 37 
 38 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
 39 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
 40 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
 41 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
 42 
 43 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
 44 double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;}
 45 double Len(Vector a){return sqrt(Dot(a , a));}
 46 
 47 Vector Normal(Vector a)
 48 {
 49     double l = Len(a);
 50     return Vector(-a.y , a.x)/l;
 51 }
 52 
 53 bool OnLeft(Line L , Point p)
 54 {
 55     return dcmp(Cross(L.v , p-L.p))>=0;
 56 }
 57 
 58 Point GetIntersection(Line a , Line b)
 59 {
 60     Vector u = a.p-b.p;
 61     double t = Cross(b.v , u)/Cross(a.v , b.v);
 62     return a.p+a.v*t;
 63 }
 64 
 65 int HalfplaneIntersection(Line *L , int n , Point *poly)
 66 {
 67     sort(L , L+n);
 68     int first , last;
 69     Point *p = new Point[n];
 70     Line *q = new Line[n];
 71     q[first=last=0]=L[0];
 72     for(int i=1 ; i<n ; i++){
 73         while(first<last && !OnLeft(L[i] , p[last-1])) last--;
 74         while(first<last && !OnLeft(L[i] , p[first])) first++;
 75         q[++last] = L[i];
 76         if(fabs(Cross(q[last].v , q[last-1].v))<eps){
 77             last--;
 78             if(OnLeft(q[last] , L[i].p)) q[last] = L[i];
 79         }
 80         if(first<last) p[last-1] = GetIntersection(q[last-1] , q[last]);
 81     }
 82     while(first<last && !OnLeft(q[first] , p[last-1])) last--;
 83     if(last-first<=1) return 0;
 84     p[last] = GetIntersection(q[last] , q[first]);
 85     int m=0 ;
 86     for(int i=first ; i<=last ; i++) poly[m++] = p[i];
 87     return m;
 88 }
 89 
 90 int n;
 91 double r;
 92 
 93 int main()
 94 {
 95   //  freopen("in.txt" , "r" , stdin);
 96     while(~scanf("%d%lf" , &n , &r)){
 97         for(int i=0 ; i<n ; i++) p[i].input();
 98         p[n] = p[0];
 99         for(int i=0 ; i<n ; i++){
100             Vector v = p[i]-p[i+1];
101             Vector t = Normal(v)*r;
102             line[i] = Line(p[i]+t , v);
103         }
104         int k = HalfplaneIntersection(line , n , poly);
105         Point p1=poly[0] , p2=poly[0];
106         double maxn = 0;
107      //   for(int i=0 ; i<k ; i++) cout<<poly[i].x<<" "<<poly[i].y<<endl;
108         for(int i=0 ; i<k ; i++){
109             for(int j=0 ; j<k ; j++){
110                 if(poly[i].dis(poly[j])-maxn>eps){
111                     p1 = poly[i] , p2 = poly[j];
112                     maxn = poly[i].dis(poly[j]);
113                 }
114             }
115         }
116         printf("%.4f %.4f %.4f %.4f\n" , p1.x , p1.y , p2.x , p2.y);
117     }
118     return 0;
119 }

 

 posted on 2015-07-23 00:09  Love风吟  阅读(288)  评论(0编辑  收藏  举报