题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=13&problem=1114&mosmsg=Submission+received+with+ID+10328241
求卡壳步骤可参考:http://cgm.cs.mcgill.ca/~orm/rotcal.html英文的解说。
最终以点积求长,叉积求宽的方式解决。。。
求卡壳步骤可参考:http://cgm.cs.mcgill.ca/~orm/rotcal.html英文的解说。
最终以点积求长,叉积求宽的方式解决。。。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<math.h>
#define eps 1e-8
#define inf 1e10
#define maxn 1020
struct point{double x,y;}points[maxn],p[maxn];
int n;
double xmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
bool cmp(const point &a,const point &b)
{
if(a.y==b.y)return a.x<b.x;
return a.y<b.y;
}
int Graham()
{
std::sort(points,points+n,cmp);
int i;
p[0]=points[0];
p[1]=points[1];
int top=1;
for(i=2;i<n;i++)
{
while(top&&xmult(p[top],points[i],p[top-1])>=0)top--;
p[++top]=points[i];
}
int mid=top;
for(i=n-2;i>=0;i--)
{
while(top>mid&&xmult(p[top],points[i],p[top-1])>=0)top--;
p[++top]=points[i];
}
return top;
}
double min(double a,double b)
{
return a>b? b: a;
}
double dmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
double distance(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double rc_minarea()//×?D???D????y
{
if(n<3)return 0;
int minx=0,maxx=0,miny=0,maxy=0;
int i;
p[n]=p[0];p[n+1]=p[1];p[n+2]=p[2];
for(i=1;i<n;i++)
{
if(p[minx].x>p[i].x||p[minx].x==p[i].x&&p[i].y<p[minx].y)minx=i;
if(p[miny].y>p[i].y||p[miny].y==p[i].y&&p[i].x<p[miny].x)miny=i;
if(p[maxx].x<p[i].x||p[maxx].x==p[i].x&&p[i].y>p[maxx].y)maxx=i;
if(p[maxy].y<p[i].y||p[maxy].y==p[i].y&&p[i].x>p[maxy].x)maxy=i;
}
int l=minx,r=maxx,t=maxy,b=miny;
double minn=(p[r].x-p[l].x)*(p[t].y-p[b].y);
double dl,dr,dt;
for(i=0;i<n;i++)
{
while(dmult(p[r+1],p[i],p[i+1])-(dl=dmult(p[r],p[i],p[i+1]))>eps)
r=(r+1)%n;
while(dmult(p[l+1],p[i+1],p[i])-(dr=dmult(p[l],p[i+1],p[i]))>eps)
l=(l+1)%n;
while(xmult(p[t+1],p[i+1],p[i])-(dt=xmult(p[t],p[i+1],p[i]))>eps)
t=(t+1)%n;
double dis=distance(p[i],p[i+1]);
minn=min(minn,dt/dis*(dl/dis+dr/dis-dis));
}
return minn;
}
int main()
{
while(scanf("%d",&n),n)
{
int i;
for(i=0;i<n;i++)
scanf("%lf%lf",&points[i].x,&points[i].y);
n=Graham();
printf("%.4lf\n",rc_minarea());
}
return 0;
}