HDU 5128 The E-pang Palace(2014广州赛区现场赛B题 计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5128

解题报告:在一个平面上给出n个点的坐标,用这n个点作为矩形的四个顶点,作两个矩形,要求两个矩形不能相交,也不能有边和点相交,然后两个矩形的面积之和要最大,求最大的面积之和是多少?如果不存在输出imp

因为n <=30,所以可以先把所有的矩形枚举出来,然后再暴力判断两两矩形组合,首先要满足位置关系,然后取面积和最大就是了.要注意的地方就是要小心一个大矩形包含一个小矩形的情况,在这种情况下,是满足位置关系的,但是,总面积只等于外面那个大矩形的面积.

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<cmath>
  7 using namespace std;
  8 const double eps = 1e-9;
  9 struct point
 10 {
 11     double x,y;
 12     point(double x = 0,double y = 0): x(x),y(y) {}
 13     friend point operator - (point a,point b)
 14     {
 15         return point(a.x-b.x,a.y-b.y);
 16     }
 17 }P[35];
 18 struct rect
 19 {
 20     point p[4];
 21 }R[1000];
 22 double dot(point a,point b)     //叉积
 23 {
 24     return a.x*b.y - b.x * a.y;
 25 }
 26 int judge_pingxing(point a,point b)
 27 {
 28     return (fabs(dot(a,b)) < eps);
 29 }
 30 double dis(point a,point b)
 31 {
 32     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 33 }
 34 int is_trang(point p1,point p2,point p3,point p4)   //判断是不是矩形
 35 {
 36     point d1 = p1 - p2;
 37     point d2 = p3 - p4;
 38     if(judge_pingxing(d1,d2))
 39     {
 40         if(p1.x > p2.x) swap(p1,p2);
 41         if(p3.x > p4.x) swap(p3,p4);
 42         d1 = p1-p2,d2 = p1-p3;
 43         point d3 = p1 - p3,d4 = p2 - p4;
 44 //        printf("%.0lf  %.0lf
",d1.x,d1.y);
 45 //        printf("%.0lf  %.0lf
",d2.x,d2.y);
 46     //    printf("%.0lf
",d1.x*d2.x+d1.y*d2.y);
 47         if(fabs(d1.x*d2.x+d1.y*d2.y) < eps && judge_pingxing(d3,d4)) return 1;
 48     }
 49     return 0;
 50 }
 51 int make(int n)     //构造矩形
 52 {
 53     int tot = 0;
 54     for(int i = 0;i < n;++i)
 55     for(int j = i+1;j < n;++j)
 56     for(int k = j+1;k < n;++k)
 57     for(int l = k+1;l < n;++l)
 58     {
 59         if(is_trang(P[i],P[j],P[k],P[l]) || is_trang(P[i],P[k],P[j],P[l]))
 60         {
 61             R[tot].p[0] = P[i];
 62             R[tot].p[1] = P[j];
 63             R[tot].p[2] = P[k];
 64             R[tot].p[3] = P[l];
 65             tot++;
 66         }
 67     }
 68     return tot;
 69 }
 70 double Max(double a,double b)
 71 {
 72     return a > b? a:b;
 73 }
 74 int is_xj(point a1,point a2,point b1,point b2)
 75 {
 76     if(dot(b1-a1,a2-a1)*dot(b2-a1,a2-a1) < 0 || fabs(dot(b1-a1,a2-a1)*dot(b2-a1,a2-a1)) < eps)
 77     if(dot(a1-b1,b2-b1)*dot(a2-b1,b2-b1) < 0 || fabs(dot(a1-b1,b2-b1)*dot(a2-b1,b2-b1)) < eps)
 78     {
 79         double m = dis(a1,b1);
 80         m = Max(m,dis(a1,b2));
 81         m = Max(m,dis(a1,a2));
 82         m = Max(m,dis(a2,b1));
 83         m = Max(m,dis(a2,b2));
 84         m = Max(m,dis(b1,b2));
 85         if(fabs(dot(a1-a2,b1-b2))<eps && m > dis(a1,a2)+dis(b1,b2)) return 0;
 86         return 1;
 87     }
 88     return 0;
 89 }
 90 struct node
 91 {
 92     point p[2];
 93 }rr1[4],rr2[4];
 94 int judge(rect a,rect b)
 95 {
 96     rr1[0].p[0] = a.p[0],rr1[0].p[1] = a.p[1];
 97     rr1[1].p[0] = a.p[0],rr1[1].p[1] = a.p[2];
 98     rr1[2].p[0] = a.p[2],rr1[2].p[1] = a.p[3];
 99     rr1[3].p[0] = a.p[1],rr1[3].p[1] = a.p[3];
100 
101     rr2[0].p[0] = b.p[0],rr2[0].p[1] = b.p[1];
102     rr2[1].p[0] = b.p[0],rr2[1].p[1] = b.p[2];
103     rr2[2].p[0] = b.p[1],rr2[2].p[1] = b.p[3];
104     rr2[3].p[0] = b.p[2],rr2[3].p[1] = b.p[3];
105     for(int i = 0;i < 4;++i)
106     for(int j = 0;j < 4;++j)
107     if(is_xj(rr1[i].p[0],rr1[i].p[1],rr2[j].p[0],rr2[j].p[1]))
108     return 0;
109 /*    for(int i = 0;i < 4;++i)     //只要枚举一个矩形的顶点是不是在另一个矩形里面或者边上
110     for(int j = i+1;j < 4;++j)
111     {
112         for(int k = 0;k < 4;++k)
113         for(int l = k+1;l < 4;++l)
114         {
115             if(is_xj(a.p[i],a.p[j],b.p[k],b.p[l]))
116             return 0;
117         }
118     }*/
119     return 1;
120 }
121 
122 bool cmp(point a,point b)
123 {
124     if(fabs(a.x-b.x) > eps)
125     return a.x < b.x;
126     else return a.y < b.y;
127 }
128 double get_area(rect a)
129 {
130     return dis(a.p[0],a.p[1]) * dis(a.p[0],a.p[2]);
131 }
132 int judge_in(rect a,rect b)
133 {
134     int flag = 0;
135     for(int i = 0;i < 4;++i)
136     {
137         if((a.p[i].x > b.p[0].x && a.p[i].x < b.p[2].x)) flag++;
138         if((a.p[i].y > b.p[0].y && a.p[i].y < b.p[1].y)) flag++;
139     }
140     return flag >= 8;
141 }
142 
143 int main()
144 {
145     //printf("%d
",is_trang(point(0,0),point(1,0),point(1,1),point(0,1)));
146 //    freopen("in","r",stdin);
147     int n;
148     while(scanf("%d",&n),n)
149     {
150         for(int i = 0;i < n;++i)
151         scanf("%lf%lf",&P[i].x,&P[i].y);
152         sort(P,P+n,cmp);
153         int tot = make(n);   //构造tot个矩形
154         double Max_ans = 0;
155         for(int i = 0;i < tot;++i)
156         sort(R[i].p,R[i].p+4,cmp);
157 //        printf("tot =  %d
",tot);
158         for(int i = 0;i < tot;++i)
159         {
160     //        for(int j = 0;j < 4;++j)
161     //        printf("%.0lf %.0lf ",R[i].p[j].x,R[i].p[j].y);
162     //        puts("");
163         }
164     //    printf("dlfjksdklj = %d
",judge_in(R[1],R[0]));
165         for(int i = 0;i < tot;++i)
166         for(int j = i;j < tot;++j)
167         if(judge(R[i],R [j]))    //满足位置关系 ,注意一个矩形包含另一个矩形的情况
168         {
169             double t = get_area(R[i]) + get_area(R[j]);    //求两个矩形的面积
170             if(judge_in(R[i],R[j]) || judge_in(R[j],R[i])) Max_ans = Max(Max_ans,Max(get_area(R[i]),get_area(R[j])));
171             else Max_ans = Max(Max_ans,t);
172         }
173         if(tot <= 0 || fabs(Max_ans) < eps) printf("imp
");
174         else printf("%.0lf
",Max_ans+eps);
175     }
176     return 0;
177 }
View Code
原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4143980.html