bzoj 1185 [HNOI2007]最小矩形覆盖(坑)

来源:互联网 发布:淘宝运营助手在哪里 编辑:程序博客网 时间:2024/05/19 21:44
毒瘤出题人...我真的做不动了
//bzoj 1185 [HNOI2007]最小矩形覆盖#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define eps 1e-8#define inf 1e15#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=100005;double ans=inf;struct point {double x,y;} p[mxn],s[mxn],c[mxn];int n,m,top;inline double dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double cross(point p0,point p1,point p2){return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}inline bool comp(point a,point b){int tmp=cross(p[0],a,b);if(tmp>0 || (tmp<=eps && dis(p[0],a)>dis(p[0],b))) return 1;return 0;}inline void graham(){int i,j;s[0]=p[0],s[1]=p[1],top=1;fo(i,2,n-1){while(top && cross(s[top-1],s[top],p[i])<0) top--;s[++top]=p[i];}top++;}inline void rc(){int i,j,q=1,a,b;fo(i,0,top-1){double h,h1,h2,high,x1,y1,x2,y2,k;while(fabs(cross(s[(q+1)%top],s[(i+1)%top],s[i]))>fabs(cross(s[q],s[(i+1)%top],s[i])))  q=(q+1)%top;high=fabs(cross(s[q],s[(i+1)%top],s[i]))/dis(s[i],s[(i+1)%top]);if(i==0) a=2,b=(q+1)%top;x1=s[(i+1)%top].x-s[i].x,y1=s[(i+1)%top].y-s[i].y;x2=s[(a+1)%top].x-s[a].x,y2=s[(a+1)%top].y-s[a].y;while(x1*x2+y1*y2>=0)  a=(a+1)%top,x2=s[(a+1)%top].x-s[a].x,y2=s[(a+1)%top].y-s[a].y;x2=s[a].x-s[i].x,y2=s[a].y-s[i].y;h1=(x1*x2+y1*y2)/dis(s[i],s[(i+1)%top]);  x2=s[(b+1)%top].x-s[b].x,y2=s[(b+1)%top].y-s[b].y;while(x1*x2+y1*y2<=0)  b=(b+1)%top,x2=s[(b+1)%top].x-s[b].x,y2=s[(b+1)%top].y-s[b].y;x1=-x1,y1=-y1;x2=s[b].x-s[(i+1)%top].x,y2=s[b].y-s[(i+1)%top].y;h2=(x1*x2+y1*y2)/dis(s[i],s[(i+1)%top]);h=h1+h2-dis(s[i],s[(i+1)%top]);if(h*high<ans){ans=h*high;x1=s[(i+1)%top].x-s[i].x,y1=s[(i+1)%top].y-s[i].y;k=h1/dis(s[i],s[(i+1)%top]);c[1]=(point){s[i].x+k*x1,s[i].y+k*y1};swap(x1,y1),x1=-x1;k=high/dis(s[i],s[(i+1)%top]);c[2]=(point){c[1].x+k*x1,c[1].y+k*y1};x1=-s[(i+1)%top].x+s[i].x,y1=-s[(i+1)%top].y+s[i].y;k=h2/dis(s[i],s[(i+1)%top]);c[3]=(point){s[(i+1)%top].x+k*x1,s[(i+1)%top].y+k*y1};swap(x1,y1),y1=-y1;k=high/dis(s[i],s[(i+1)%top]);c[4]=(point){c[3].x+k*x1,c[3].y+k*y1};swap(c[3],c[4]);}}printf("%.5lf\n",ans);double mn=c[1].y;int k=1;fo(i,2,4)  if(mn>c[i].y) mn=c[i].y,k=i;  else if(fabs(mn-c[i].y)<=eps && c[i].x<c[k].x) k=i;fo(i,0,3){if(k+i<=4)  printf("%.5lf %.5lf\n",c[k+i].x,c[k+i].y);else   printf("%.5lf %.5lf\n",c[k+i-4].x,c[k+i-4].y);}}int main(){int i,j,u=0;scanf("%d",&n);fo(i,0,n-1)  scanf("%lf%lf",&p[i].x,&p[i].y);fo(i,1,n-1)  if(p[u].y>p[i].y || (p[u].y-p[i].y)<=eps && p[u].x>p[i].x)    u=i;swap(p[0],p[u]);sort(p+1,p+n,comp);graham(),rc();return 0;}