题目大意:
给定一个多边形,给定一个圆的半径,要求在多边形中放置两个同样半径的圆,可相互覆盖,但不能超出多边形的范围,希望两个圆的面积覆盖和最大
输出任意一组满足的圆的圆心点
如果两个圆不相互覆盖,那么必然达到最大面积
如果相互覆盖,可以换一种方式考虑,因为两个圆是一样的,两个圆的距离越长,那么相互覆盖的面积必然越小
所以可以将多边形内推进半径的长度
然后在半平面交后得到的多边形中找到距离最远的两个点
仔细想一想可以知道多边形上最远距离的点,必然是两个顶点的距离
所以平方的方法就可以求解了
当然用旋转卡壳的话在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 }
我还在坚持,我还未达到我所想,梦~~一直在