题目大意

用最小矩形覆盖平面上所有的点

分析

有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小

简略证明

我们逆时针枚举一条边

用旋转卡壳维护此时最左,最右,最上的点

注意

注意凸包后点数不再是n

吐槽

凸包后点数是n,bzoj上就过了???

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
typedef double db;
const db eps=1e-9;
const int M=50007; int n; struct pt{
db x,y;
pt(db _x=0.0,db _y=0.0){x=_x; y=_y;}
}p[M],s[M]; int tot; bool eq(db x,db y){return fabs(y-x)<=eps;}
bool le(db x,db y){return eq(x,y)||x<y;} pt operator -(pt x,pt y){return pt(x.x-y.x,x.y-y.y);}
pt operator +(pt x,pt y){return pt(x.x+y.x,x.y+y.y);}
bool operator <(pt x,pt y){return (x.y!=y.y)?(x.y<y.y):(x.x<y.x);}
bool operator ==(pt x,pt y){return eq(x.x,y.x)&&eq(x.y,y.y);};
pt operator *(pt x,db d){return pt(x.x*d,x.y*d);}
pt operator /(pt x,db d){return pt(x.x/d,x.y/d);} db dot(pt x,pt y){
return x.x*y.x+x.y*y.y;
} db cross(pt x,pt y){
return x.x*y.y-x.y*y.x;
} db length(pt x){
return sqrt(dot(x,x));
} db area(pt x,pt y,pt z){
return cross(y-x,z-x);
} db shadow(pt x,pt y,pt to){
return dot(y-x,to-x)/length(to-x);
} pt lf_90(pt x){
return pt(-x.y,x.x);
} bool cmp(pt x,pt y){
db tp=area(p[1],x,y);
if(eq(tp,0)) return length(x-p[1])<length(y-p[1]);
return tp>0;
} void convex(){
int i,ii=1;
for(i=2;i<=n;i++) if(p[i]<p[ii]) ii=i;
swap(p[1],p[ii]);
sort(p+2,p+n+1,cmp); s[tot=1]=p[1];
for(i=2;i<=n;i++){
while(tot>1&&le(area(s[tot-1],s[tot],p[i]),0)) tot--;
s[++tot]=p[i];
}
} int main(){
int i,p1,p2,p3;
db tp1,tp2,tp3,tp4,ans;
pt a[5],tp; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); convex(); s[0]=s[tot];//要算每一条边,加上tot-0的 ans=1e32;
p1=1,p2=1,p3=1; for(i=0;i<tot;i++){
if(s[i]==s[i+1]) continue; while(le(area(s[i],s[i+1],s[p3]),area(s[i],s[i+1],s[p3%tot+1]))) p3=p3%tot+1;
if(i==0) p1=p3;//第一次找卡壳特例
while(le(shadow(s[i],s[p1%tot+1],s[i+1]),shadow(s[i],s[p1],s[i+1]))) p1=p1%tot+1;
while(le(shadow(s[i+1],s[p2%tot+1],s[i]),shadow(s[i+1],s[p2],s[i]))) p2=p2%tot+1; tp1=length(s[i+1]-s[i]);
tp2=area(s[i],s[i+1],s[p3])/tp1;
tp3=fabs(shadow(s[i],s[p1],s[i+1]));
tp4=fabs(shadow(s[i+1],s[p2],s[i])); if(le((tp1+tp3+tp4)*tp2,ans)){
ans=(tp1+tp3+tp4)*tp2;
tp=s[i+1]-s[i];
a[1]=s[i]-tp*(tp3/tp1);
a[2]=s[i+1]+tp*(tp4/tp1);
tp=lf_90(tp);
a[3]=a[2]+tp*(tp2/tp1);
a[4]=a[1]+tp*(tp2/tp1);
}
} printf("%.5lf\n",ans+eps); int ii=1;
for(i=2;i<=4;i++) if(a[i]<a[ii]) ii=i;
printf("%.5lf %.5lf\n",a[ii].x+eps,a[ii].y+eps);
for(i=ii%4+1;i!=ii;i=i%4+1) printf("%.5lf %.5lf\n",a[i].x+eps,a[i].y+eps); return 0;
}

bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳的更多相关文章

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

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

  2. 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

    题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...

  3. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

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

  4. BZOJ:1185: [HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 这计算几何……果然很烦…… 发现自己不会旋转卡壳,补了下,然后发现求凸包也不会…… 凸包:找一个最左下的点,其他点按照与它连边的夹角排序,然后维护一个栈用 ...

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

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

  6. BZOJ 1185 [HNOI2007]最小矩形覆盖:凸包 + 旋转卡壳

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 题意: 给出二维平面上的n个点,问你将所有点覆盖的最小矩形面积. 题解: 先找出凸 ...

  7. bzoj 1185 [HNOI2007]最小矩形覆盖——旋转卡壳

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 矩形一定贴着凸包的一条边.不过只是感觉这样. 枚举一条边,对面的点就是正常的旋转卡壳. ...

  8. BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...

  9. ●BZOJ 1185 [HNOI2007]最小矩形覆盖

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解: 计算几何,凸包,旋转卡壳 结论:矩形的某一条边在凸包的一条边所在的直线上. ( ...

随机推荐

  1. js中异步方案比较完整版(callback,promise,generator,async)

    JS 异步已经告一段落了,这里来一波小总结 1. 回调函数(callback) setTimeout(() => { // callback 函数体 }, 1000) 缺点:回调地狱,不能用 t ...

  2. C#算术运算符

    一.C#算术运算符 C#语言的算术运算符主要用于数学计算中. 二.示例 using System;using System.Collections.Generic;using System.Linq; ...

  3. MySql下最好用的数据库管理工具是哪个

    MySql下最好用的数据库管理工具是哪个? 维基上有个很全的列表: https://en.wikipedia.org/wiki/Comparison_of_database_tools   1. ph ...

  4. const 修饰成员函数 前后用法(effective c++ 03)

    目录 const在函数后面 const修饰成员函数的两个作用 const在函数前面 总结 const在函数后面 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态 ...

  5. 【上下界网络流 费用流】bzoj2055: 80人环游世界

    EK费用流居然写错了…… Description     想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么     一个80人的团 ...

  6. python中打印金字塔和九九乘法表的几种方法

    # 打印九九乘法表for i in range(1,10): for j in range(1,i+1): # x=i*j # print(i,'*',j,'=',x,end=' ') print(' ...

  7. ProC第一弹

    编译pro*c 的makefile例子 原来只需在makefile中追加include $(ORACLE_HOME)/precomp/lib/env_precomp.mk,其他一切按照makefile ...

  8. Linux扩增卷组、逻辑卷以及缩减逻辑卷

    今天我们将了解怎样来扩展卷组,扩展和缩减逻辑卷.在这里,我们可以缩减或者扩展逻辑卷管理(LVM)中的分区,LVM也可称之为弹性卷文件系统. 前置需求使用LVM创建弹性磁盘存储——第一部分 什么时候我们 ...

  9. 解决VMware vSphere Client无法连接ESXi虚拟主机方法

    1 一般情况下重启services.sh就可以解决(或图形界面下restart management agent)services.sh restart2 若重启services.sh报错且仍然无法连 ...

  10. Maven本地库在哪?

    Maven的本地存储库是一个本地文件夹,用于存储你的所有项目的依赖项(插件Jars和其他Maven下载的文件).简单的说,当你建立一个Maven项目,所有依赖文件将存储在Maven的本地库. 默认情况 ...