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

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

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

 

来自大佬的建议:输出double时用%f

 

#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[N],C[N];
 
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);
    }
}

 

posted @ 2018-01-10 10:53  TRTTG  阅读(208)  评论(0编辑  收藏  举报