您的位置:首页 > 其它

bzoj千题计划209:bzoj1185: [HNOI2007]最小矩形覆盖

2018-01-10 10:53 381 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1185

题解去看它

http://www.cnblogs.com/TheRoadToTheGold/p/8253800.html

精度真是卡的我醉生梦死,w(゚Д゚)w O(≧口≦)O

bzoj改成long double 就过了

洛谷仍处于

输出x.99999,答案输出x+1.00000

输出-0.00000,答案输出0.00000

救命啊~~~~(>_<)~~~~

[b]来自大佬的建议:输出double时用%f[/b]

#include<cmath>
#include<cstdio>
#include<algorithm>

#define N 50001

using namespace std;

const long double eps=1e-10;

int dcmp(long double x)
{
if(fabs(x)<eps) return 0;
return x<0 ? -1 : 1;
}

struct Point
{
long double x,y;

Point(long double x=0,long double y=0) : x(x),y(y) { }

bool operator < (Point p) const
{
if(!dcmp(x-p.x)) return y<p.y;
return x<p.x;
}

bool operator == (Point p) const
{
return !dcmp(x-p.x) && !dcmp(y-p.y);
}
};

typedef Point Vector;

Point P
,C
;

Point AnsP[4];

Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); }
Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); }
Vector operator * (Vector A,double q) { return Vector(A.x*q,A.y*q); }

long double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}

long double Area2(Point A,Point B,Point D)
{
return Cross(B-A,D-A);
}

long double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}

long double Length(Vector A)
{
return sqrt(Dot(A,A));
}

int ConvexHull(Point *p,int n,Point *c)
{
sort(p,p+n);
n=unique(p,p+n)-p;
int m=0;
for(int i=0;i<n;++i)
{
while(m>1 && Cross(c[m-1]-c[m-2],p[i]-c[m-2])<=0) m--;
c[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;--i)
{
while(m>k && Cross(c[m-1]-c[m-2],p[i]-c[m-2])<=0) m--;
c[m++]=p[i];
}
m--;
return m;
}

long double getdis(Point A,Point B)
{
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

void RotatingCaliper(Point *c,int m)
{
long double AnsArea=1e20,AnsPeri=1e20;
int q=1,l=0,r=0;
long double d,h,w,rw;
for(int p=0;p<m;++p)
{
while(fabs(Cross(c[p]-c[p+1],c[q+1]-c[p+1]))>fabs(Cross(c[p]-c[p+1],c[q]-c[p+1]))) q=(q+1)%m;
while(dcmp(Dot(c[p+1]-c[p],c[r+1]-c[r]))>0)
r=(r+1)%m;
if(!l) l=q;
while(dcmp(Dot(c[p+1]-c[p],c[l+1]-c[l]))<0)
l=(l+1)%m;
d=Length(c[p+1]-c[p]);
h=fabs(Area2(c[p],c[p+1],c[q]))/d;
w=Dot(c[p+1]-c[p],c[r]-c[l])/d;
rw=Dot(c[r]-c[p],c[p+1]-c[p])/d;
if(w*h<AnsArea)
{
AnsArea=w*h;
AnsP[0]=c[p]+(c[p+1]-c[p])*(rw/d);
AnsP[1]=AnsP[0]+(c[r]-AnsP[0])*(h/getdis(c[r],AnsP[0]));
AnsP[2]=AnsP[1]+(c[q]-AnsP[1])*(w/getdis(c[q],AnsP[1]));
AnsP[3]=AnsP[2]+(c[l]-AnsP[2])*(h/getdis(c[l],AnsP[2]));
}
}
double out=AnsArea;
printf("%.5lf\n",out);
}

bool less(Point A,Point B)
{
if(!dcmp(A.y-B.y)) return A.x<B.x;
return A.y<B.y;
}

int main()
{
int n,m;
scanf("%d",&n);
double x,y;
for(int i=0;i<n;++i)
{
scanf("%lf%lf",&x,&y);
P[i]=Point(x,y);
}
m=ConvexHull(P,n,C);
RotatingCaliper(C,m);
int s=0;
for(int i=1;i<4;++i)
if(less(AnsP[i],AnsP[s])) s=i;
double outx,outy;
for(int i=0;i<4;++i)
{
if(!dcmp(AnsP[(i+s)%4].x)) AnsP[(i+s)%4].x=0;
if(!dcmp(AnsP[(i+s)%4].y)) AnsP[(i+s)%4].y=0;
outx=AnsP[(i+s)%4].x+eps;
outy=AnsP[(i+s)%4].y+eps;
printf("%.5lf %.5lf\n",outx,outy);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: