BZOJ 1185 HNOI2007 最小矩形覆盖 旋转卡壳

来源:互联网 发布:网络支付异地消费短信 编辑:程序博客网 时间:2024/05/29 00:31

题目大意:最小矩形覆盖

首先有一个结论:凸包上一定有一条边与矩形的一条边重合

证明:如果不存在一条边与矩形的一条边重合,那么我将这个矩形旋转一下一定会比之前更小

于是我们枚举其中一条边,对其余三个点卡壳即可

这旋转卡壳写的真叫一个卡壳- - 还好1A掉了- -

#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 50500#define EPS 1e-7using namespace std;struct Point{double x,y;Point() {}Point(double _,double __):x(_),y(__) {}friend istream& operator >> (istream &_,Point &p){scanf("%lf%lf",&p.x,&p.y);return _;}bool operator < (const Point &p) const{if(fabs(x-p.x)<EPS)return y<p.y;return x<p.x;}Point operator + (const Point &p) const{return Point(x+p.x,y+p.y);}Point operator - (const Point &p) const{return Point(x-p.x,y-p.y);}double operator * (const Point &p) const{return x*p.y-y*p.x;}Point operator * (const double &rate) const{return Point(x*rate,y*rate);}friend ostream& operator << (ostream& _,const Point &p){printf("%.5lf %.5lf",p.x,p.y);return _;}}points[M];struct Line{Point p,v;Line() {}Line(const Point &_,const Point &__):p(_),v(__) {}};int n,top;double ans=1e15;Point ans_points[4];Point *stack[M<<1];Point Get_Intersection(const Line &l1,const Line &l2){Point u=l1.p-l2.p;double temp=(l2.v*u)/(l1.v*l2.v);return l1.p+l1.v*temp;}void Get_Convex_Hull(){static Point *stack[M];int i,top=0;for(i=1;i<=n;i++){while( top>=2 && (*stack[top]-*stack[top-1])*(points[i]-*stack[top])>=-EPS )stack[top--]=0x0;stack[++top]=&points[i];}for(i=1;i<=top;i++)::stack[++::top]=stack[i];top=0;for(i=1;i<=n;i++){while( top>=2 && (*stack[top]-*stack[top-1])*(points[i]-*stack[top])<=EPS )stack[top--]=0x0;stack[++top]=&points[i];}for(i=top-1;i>1;i--)::stack[++::top]=stack[i];int limit=::top;for(i=1;i<=limit;i++)::stack[++::top]=::stack[i];::stack[++::top]=::stack[1];}void Rotating_Calipers(){int limit=top>>1;Point **p1,**p2,**p3,**p4;p1=stack+1;Point v1=(**(p1+1)-**p1);Point v2(v1.y,-v1.x);Point v3(v2.y,-v2.x);Point v4(v3.y,-v3.x);for(p2=p1;(**(p2+1)-**p2)*v2<0;p2++);for(p3=p2;(**(p3+1)-**p3)*v3<0;p3++);for(p4=p3;(**(p4+1)-**p4)*v4<0;p4++);for(;p1<=stack+limit;p1++){v1=(**(p1+1)-**p1);v2=Point(v1.y,-v1.x);v3=Point(v2.y,-v2.x);v4=Point(v3.y,-v3.x);for(;(**(p2+1)-**p2)*v2<0;p2++);for(;(**(p3+1)-**p3)*v3<0;p3++);for(;(**(p4+1)-**p4)*v4<0;p4++);Point temp_points[4];Line l1(**p1,v1);Line l2(**p2,v2);Line l3(**p3,v3);Line l4(**p4,v4);temp_points[0]=Get_Intersection(l1,l4);temp_points[1]=Get_Intersection(l4,l3);temp_points[2]=Get_Intersection(l3,l2);temp_points[3]=Get_Intersection(l2,l1);double area=(temp_points[1]-temp_points[0])*(temp_points[3]-temp_points[0]);if(area<ans)memcpy(ans_points,temp_points,sizeof ans_points),ans=area;}}int main(){int i;cin>>n;for(i=1;i<=n;i++)cin>>points[i];sort(points+1,points+n+1);Get_Convex_Hull();Rotating_Calipers();printf("%.5lf\n",ans);int st=0;for(i=1;i<4;i++)if( ans_points[i].y<ans_points[st].y ||fabs(ans_points[i].y-ans_points[st].y)<EPS && ans_points[i].x<ans_points[st].x )st=i;for(i=0;i<4;i++)cout<<ans_points[i+st&3]<<endl;return 0;}


0 0
原创粉丝点击