求出凸包后,矩形的一条边一定与凸包的某条边重合。

枚举每条边,求出离它最远的点和离它最左最右的点,因为那三个点是单调变化的,所以复杂度为$O(n)$。

注意精度。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 50010
using namespace std;
typedef double D;
struct P{D x,y;P(){}P(D _x,D _y){x=_x,y=_y;}}p[N],pp[N],hull[N],pivot,A,B,C,rect[8];
int n,i,j,l,r,k;
D w,h,ans=1e20,tmp,len;
bool del[N];
inline int zero(D x){return fabs(x)<1e-4;}
inline int sig(D x){if(fabs(x)<1e-8)return 0;return x>0?1:-1;}
inline D cross(P A,P B,P C){return(B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);}
inline D distsqr(P A,P B){return(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);}
inline bool cmp(P a,P b){
D t=cross(pivot,a,b);
return sig(t)==1||sig(t)==0&&sig(distsqr(pivot,a)-distsqr(pivot,b))==-1;
}
inline void convexhull(int n,P stck[],int&m){
int i,k,top;
for(i=0;i<n;i++)pp[i]=p[i];
for(k=0,i=1;i<n;i++)if(pp[i].y<pp[k].y||(pp[i].y==pp[k].y&&pp[i].x<pp[k].x))k=i;
pivot=pp[k];pp[k]=pp[0];pp[0]=pivot;
sort(pp+1,pp+n,cmp);
stck[0]=pp[0];stck[1]=pp[1];
for(top=1,i=2;i<n;i++){
while(top&&sig(cross(pp[i],stck[top],stck[top-1]))>=0)--top;
stck[++top]=pp[i];
}
m=top+1;
}
inline D area(P A,P B,P C){return fabs(cross(A,B,C));}
inline P vertical(P A,P B){return P(A.x-B.y+A.y,A.y+B.x-A.x);}
int main(){
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
convexhull(n,hull,n);
for(i=1;i<n;i++)if(zero(hull[i].x-hull[i-1].x)&&zero(hull[i].y-hull[i-1].y))del[i]=1;
for(k=i=0;i<n;i++)if(!del[i])hull[k++]=hull[i];
for(hull[n=k]=hull[i=0];i<n;i++){
A=hull[i],B=hull[i+1],C=vertical(A,B);
while(sig(area(A,B,hull[j])-area(A,B,hull[j+1]))<1)j=(j+1)%n;
while(sig(cross(A,C,hull[l])-cross(A,C,hull[l+1]))<1)l=(l+1)%n;
while(sig(cross(A,C,hull[r])-cross(A,C,hull[r+1]))>-1)r=(r+1)%n;
len=sqrt(distsqr(A,B));
h=area(A,B,hull[j])/len;
w=(cross(A,C,hull[l])-cross(A,C,hull[r]))/len;
if(sig(h*w-ans)==-1){
ans=h*w;
tmp=area(A,B,hull[l])/len/len;
rect[0]=P(hull[l].x+tmp*(A.x-C.x),hull[l].y+tmp*(A.y-C.y));
tmp=h/len;
rect[3]=P(rect[0].x+tmp*(C.x-A.x),rect[0].y+tmp*(C.y-A.y));
tmp=w/len;
rect[1]=P(rect[0].x+tmp*(B.x-A.x),rect[0].y+tmp*(B.y-A.y));
rect[2]=P(rect[3].x+tmp*(B.x-A.x),rect[3].y+tmp*(B.y-A.y));
}
}
for(i=0;i<4;i++)rect[i+4]=rect[i];
for(j=0,i=1;i<4;i++)if(sig(rect[i].y-rect[j].y)==-1||sig(rect[i].y-rect[j].y)==0&&sig(rect[i].x-rect[j].x)==-1)j=i;
printf("%.0f.00000\n",ans);
for(i=0;i<4;i++)printf("%.0f.00000 %.0f.00000\n",rect[j+i].x,rect[j+i].y);
return 0;
}

  

BZOJ1185 : [HNOI2007]最小矩形覆盖的更多相关文章

  1. BZOJ1185[HNOI2007] 最小矩形覆盖(旋转卡壳)

    BZOJ1185[HNOI2007] 最小矩形覆盖 题面 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点的坐标 分析 首先可以先求凸包,因为覆盖了凸包上的顶点,凸 ...

  2. bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包

    [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2081  Solved: 920 ...

  3. BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】

    题目链接 BZOJ1185 题解 最小矩形一定有一条边在凸包上,枚举这条边,然后旋转卡壳维护另外三个端点即可 计算几何细节极多 维护另外三个端点尽量不在这条边上,意味着左端点尽量靠后,右端点尽量靠前, ...

  4. 2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)

    传送门 不难看出最后的矩形一定有一条边与凸包某条边重合. 因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案. 代码: #include<bits/stdc++.h> #define ...

  5. [BZOJ1185][HNOI2007]最小矩形覆盖-[凸包+旋转卡壳]

    Description 传送门 Solution 感性理解一下,最小矩形一定是由一条边和凸包上的边重合的. 然后它就是模板题了..然而真的好难调,小于大于动不动就打错. Code #include&l ...

  6. BZOJ1185 HNOI2007 最小矩形覆盖 凸包、旋转卡壳

    传送门 首先,肯定只有凸包上的点会限制这个矩形,所以建立凸包. 然后可以知道,矩形上一定有一条边与凸包上的边重合,否则可以转一下使得它重合,答案会更小. 于是沿着凸包枚举这一条边,通过旋转卡壳找到离这 ...

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解去看它 http://www.cnblogs.com/TheRoadToTheGold/p ...

  8. 【BZOJ1185】[HNOI2007]最小矩形覆盖(凸包,旋转卡壳)

    [BZOJ1185][HNOI2007]最小矩形覆盖(凸包,旋转卡壳) 题面 BZOJ 洛谷 题解 最小的矩形一定存在一条边在凸包上,那么枚举这条边,我们还差三个点,即距离当前边的最远点,以及做这条边 ...

  9. 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1945  Solve ...

随机推荐

  1. [转]结合轮廓显示,实现完整的框选目标(附Demo代码)

    原地址:http://www.cnblogs.com/88999660/articles/2887078.html 几次看见有人问框选物体的做法,之前斑竹也介绍过,用画的框生成的视椎,用经典图形学的视 ...

  2. [Unity3D]计时器/Timer

    原地址:http://blog.sina.com.cn/s/blog_5b6cb9500101aejs.html https://github.com/xuzhiping7/Unity3d-Timer ...

  3. Procrustes Analysis普氏分析法

    选取N幅同类目标物体的二维图像,并用上一篇博文的方法标注轮廓点,这样就得到训练样本集: 由于图像中目标物体的形状和位置存在较大偏差,因此所得到的数据并不具有仿射不变性,需要对其进行归一化处理.这里采用 ...

  4. 减小Delphi2010程序的尺寸(关闭RTTI反射机制)

    自从Delphi2010增强了RTTI反射机制后,编译出来的程序变得更大了,这是因为默认情况下 Delphi2010 给所有类都加上了RTTI信息(呵呵,不管你用不用它,好像实用价值确实不高,至少目前 ...

  5. Java获取、删除文件和目录

    package javatest; import java.io.File; import java.util.ArrayList; import java.util.regex.Pattern; c ...

  6. cookie注入讲解

    我们首先还是来看看中网景论坛的最新版本"(CNKBBS2007)中网景论坛2007v5.0 "官方下载地址" http://www.cnetking.com/websys ...

  7. python遍历数组的两种方法

    第一种,最常用的,通过for in遍历数组 1 2 3 4 5 6 7 8 colours = ["red","green","blue"] ...

  8. raw格式镜像文件压缩并转换为qcow2格式

    raw格式文件,这个比较占用空间,你可以用以下命令将其压缩并转换成qcow2格式. # virt-sparsify --compress --convert qcow2 ubuntu.img ubun ...

  9. Product of Array Exclude Itself

    Given an integers array A. Define B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], calculate B WI ...

  10. window常用软件

    ftpserver QQ asc pan 屏保 view putty 迅雷 teamviewer绿色 teamviewer单文件 魔方 chrome winscp WinRAR xshell 鲁大师 ...