您的位置:首页 > 其它

uva 10173 Smallest Bounding Rectangle (计算几何-凸包)

2013-08-31 15:53 405 查看
ProblemF

SmallestBoundingRectangle

Input:standardinput

Output:standardoutput

TimeLimit:3seconds

GiventheCartesiancoordinatesofn(>0)2-dimensionalpoints,writeaprogramthatcomputestheareaoftheirsmallestboundingrectangle(smallestrectanglecontainingallthegivenpoints).

Input

Theinputfilemaycontainmultipletestcases.Eachtestcasebeginswithalinecontainingapositiveintegern(<1001)indicatingthenumberofpointsinthistestcase.Thenfollowsnlineseachcontainingtworealnumbersgivingrespectively
thex-andy-coordinatesofapoint.Theinputterminateswithatestcasecontainingavalue0forn
whichmustnotbeprocessed.

Output

Foreachtestcaseintheinputprintalinecontainingtheareaofthesmallestboundingrectangleroundedtothe4thdigitafterthedecimalpoint.

SampleInput

3

-3.0005.000

7.0009.000

17.0005.000

4

10.00010.000

10.00020.000

20.00020.000

20.00010.000

0

SampleOutput

80.0000

100.0000

RezaulAlamChowdhury


“Theartofmathematics,asoflife,isknowingwhichtruthsareuseless.”


我的解题思路:我是猜的,最小的矩形一定经过所有点围成的凸包的一条边,因此枚举凸包的边即可。效率O(n^2)


虽然无法证明,但是AC了,说明我的想法是比较正确的。


#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
usingnamespacestd;

constintmaxn=1010;
constdoubleeps=1e-9;
constdoublepi=acos(double(-1));

structpoint{
doublex,y;
point(doublex0=0,doubley0=0):x(x0),y(y0){}
friendbooloperator<(pointa,pointb){
if(a.y!=b.y)returna.y<b.y;
elsereturna.x<b.x;
}
doublegetdis(pointq){
returnsqrt((x-q.x)*(x-q.x)+(y-q.y)*(y-q.y));
}
}p[maxn];

structline{//Lineax+by+c=0
doublea,b,c;
line(doublea0=0,doubleb0=0,doublec0=0){
a=a0;
b=b0;
c=c0;
}
doublegetpdis(pointq){
returnabs(a*q.x+b*q.y+c)/sqrt(a*a+b*b);
}
};

intn,top;

doublexchen(pointa,pointb,pointc){
return(b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}

doubledchen(pointa,pointb,pointc){
return(b.x-a.x)*(c.x-a.x)+(c.y-a.y)*(b.y-a.y);
}

boolcmp(pointa,pointb){
if(fabs(xchen(p[0],a,b))<eps)returna.getdis(p[0])<b.getdis(p[0]);
elsereturnxchen(p[0],a,b)>0;
}

voiddeal(){
top=1;
sort(p,p+n);
sort(p+1,p+n,cmp);
for(inti=2;i<n;i++){
while(top>0&&xchen(p[top-1],p[top],p[i])<=0)top--;
p[++top]=p[i];
}
p[++top]=p[0];
}

voidinput(){
for(inti=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
}

linegetL(pointp1,pointp2){//getthelinethatcrosspointp1andp2
//a=y1-y2,b=x2-x1,c=x1*y2-x2*y1;
linetmp;
tmp.a=p1.y-p2.y;
tmp.b=p2.x-p1.x;
tmp.c=p1.x*p2.y-p2.x*p1.y;
//cout<<tmp.a<<""<<tmp.b<<""<<tmp.c<<endl;
returntmp;
}

linegetpl(linel,pointq){
linetmp=l;
tmp.a=-l.b;
tmp.b=l.a;
tmp.c=-tmp.a*q.x-tmp.b*q.y;
returntmp;
}

pointgetCrossPoint(linel1,linel2){//getthecrosspointoflinel1andl2
pointtmp;
tmp.x=(l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l1.b*l2.a);
tmp.y=(l1.c*l2.a-l2.c*l1.a)/(l1.a*l2.b-l1.b*l2.a);
returntmp;
}

voidcomputing(){
doubleans=1e12;
deal();
for(inti=0;i<top;i++){
linel=getL(p[i],p[i+1]);
pointlpoint(1e12,1e12),rpoint(-1e12,-1e12),tmp;
doublemaxh=0;
for(inti=0;i<top;i++){
doubletmpdis=l.getpdis(p[i]);
if(tmpdis>maxh)maxh=tmpdis;
tmp=getCrossPoint(l,getpl(l,p[i]));
if(tmp.x<lpoint.x-eps)lpoint=tmp;
if(fabs(tmp.x-lpoint.x)<eps&&tmp.y<lpoint.y)lpoint=tmp;
if(tmp.x>rpoint.x)rpoint=tmp;
if(fabs(tmp.x-rpoint.x)<eps&&tmp.y>rpoint.y)rpoint=tmp;
}
if(lpoint.getdis(rpoint)*maxh<ans)ans=lpoint.getdis(rpoint)*maxh;
}
printf("%.4lf\n",ans);
}

intmain(){
while(scanf("%d",&n)!=EOF&&n>0){
input();
computing();
}
return0;
}


[/code]



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: