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

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

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

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

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps = 1e-;
struct point
{
double x,y;
point(double x = ,double y = ): x(x),y(y) {}
friend point operator - (point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
}P[];
struct rect
{
point p[];
}R[];
double dot(point a,point b) //叉积
{
return a.x*b.y - b.x * a.y;
}
int judge_pingxing(point a,point b)
{
return (fabs(dot(a,b)) < eps);
}
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int is_trang(point p1,point p2,point p3,point p4) //判断是不是矩形
{
point d1 = p1 - p2;
point d2 = p3 - p4;
if(judge_pingxing(d1,d2))
{
if(p1.x > p2.x) swap(p1,p2);
if(p3.x > p4.x) swap(p3,p4);
d1 = p1-p2,d2 = p1-p3;
point d3 = p1 - p3,d4 = p2 - p4;
// printf("%.0lf %.0lf\n",d1.x,d1.y);
// printf("%.0lf %.0lf\n",d2.x,d2.y);
// printf("%.0lf\n",d1.x*d2.x+d1.y*d2.y);
if(fabs(d1.x*d2.x+d1.y*d2.y) < eps && judge_pingxing(d3,d4)) return ;
}
return ;
}
int make(int n) //构造矩形
{
int tot = ;
for(int i = ;i < n;++i)
for(int j = i+;j < n;++j)
for(int k = j+;k < n;++k)
for(int l = k+;l < n;++l)
{
if(is_trang(P[i],P[j],P[k],P[l]) || is_trang(P[i],P[k],P[j],P[l]))
{
R[tot].p[] = P[i];
R[tot].p[] = P[j];
R[tot].p[] = P[k];
R[tot].p[] = P[l];
tot++;
}
}
return tot;
}
double Max(double a,double b)
{
return a > b? a:b;
}
int is_xj(point a1,point a2,point b1,point b2)
{
if(dot(b1-a1,a2-a1)*dot(b2-a1,a2-a1) < || fabs(dot(b1-a1,a2-a1)*dot(b2-a1,a2-a1)) < eps)
if(dot(a1-b1,b2-b1)*dot(a2-b1,b2-b1) < || fabs(dot(a1-b1,b2-b1)*dot(a2-b1,b2-b1)) < eps)
{
double m = dis(a1,b1);
m = Max(m,dis(a1,b2));
m = Max(m,dis(a1,a2));
m = Max(m,dis(a2,b1));
m = Max(m,dis(a2,b2));
m = Max(m,dis(b1,b2));
if(fabs(dot(a1-a2,b1-b2))<eps && m > dis(a1,a2)+dis(b1,b2)) return ;
return ;
}
return ;
}
struct node
{
point p[];
}rr1[],rr2[];
int judge(rect a,rect b)
{
rr1[].p[] = a.p[],rr1[].p[] = a.p[];
rr1[].p[] = a.p[],rr1[].p[] = a.p[];
rr1[].p[] = a.p[],rr1[].p[] = a.p[];
rr1[].p[] = a.p[],rr1[].p[] = a.p[]; rr2[].p[] = b.p[],rr2[].p[] = b.p[];
rr2[].p[] = b.p[],rr2[].p[] = b.p[];
rr2[].p[] = b.p[],rr2[].p[] = b.p[];
rr2[].p[] = b.p[],rr2[].p[] = b.p[];
for(int i = ;i < ;++i)
for(int j = ;j < ;++j)
if(is_xj(rr1[i].p[],rr1[i].p[],rr2[j].p[],rr2[j].p[]))
return ;
/* for(int i = 0;i < 4;++i) //只要枚举一个矩形的顶点是不是在另一个矩形里面或者边上
for(int j = i+1;j < 4;++j)
{
for(int k = 0;k < 4;++k)
for(int l = k+1;l < 4;++l)
{
if(is_xj(a.p[i],a.p[j],b.p[k],b.p[l]))
return 0;
}
}*/
return ;
} bool cmp(point a,point b)
{
if(fabs(a.x-b.x) > eps)
return a.x < b.x;
else return a.y < b.y;
}
double get_area(rect a)
{
return dis(a.p[],a.p[]) * dis(a.p[],a.p[]);
}
int judge_in(rect a,rect b)
{
int flag = ;
for(int i = ;i < ;++i)
{
if((a.p[i].x > b.p[].x && a.p[i].x < b.p[].x)) flag++;
if((a.p[i].y > b.p[].y && a.p[i].y < b.p[].y)) flag++;
}
return flag >= ;
} int main()
{
//printf("%d\n",is_trang(point(0,0),point(1,0),point(1,1),point(0,1)));
// freopen("in","r",stdin);
int n;
while(scanf("%d",&n),n)
{
for(int i = ;i < n;++i)
scanf("%lf%lf",&P[i].x,&P[i].y);
sort(P,P+n,cmp);
int tot = make(n); //构造tot个矩形
double Max_ans = ;
for(int i = ;i < tot;++i)
sort(R[i].p,R[i].p+,cmp);
// printf("tot = %d\n",tot);
for(int i = ;i < tot;++i)
{
// for(int j = 0;j < 4;++j)
// printf("%.0lf %.0lf ",R[i].p[j].x,R[i].p[j].y);
// puts("");
}
// printf("dlfjksdklj = %d\n",judge_in(R[1],R[0]));
for(int i = ;i < tot;++i)
for(int j = i;j < tot;++j)
if(judge(R[i],R [j])) //满足位置关系 ,注意一个矩形包含另一个矩形的情况
{
double t = get_area(R[i]) + get_area(R[j]); //求两个矩形的面积
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])));
else Max_ans = Max(Max_ans,t);
}
if(tot <= || fabs(Max_ans) < eps) printf("imp\n");
else printf("%.0lf\n",Max_ans+eps);
}
return ;
}
上一篇:IBM中国研究院、SAP、网易游戏、IBM2015应届生招聘笔试面试问题分享


下一篇:搞IT的应届生如何写好简历?