1185: [HNOI2007]最小矩形覆盖

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge

Submit: 1114  Solved: 505

[Submit][Status][

id=1185" style="color:blue; text-decoration:none">Discuss]

Description

凸包+旋转卡壳

首先有一个结论:矩形一定有一条边在凸包上,否则我们旋转之后一定会得到一个更小的矩形,脑补一下。

然后枚举凸包上的边,用旋转卡壳维护矩形的另外三条边,同一时候更新答案就可以。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<set>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 50005
#define eps 1e-8
#define inf 1e60
using namespace std;
int n,top;
double mn=inf;
struct data
{
double x,y;
friend bool operator ==(data a,data b){return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;}
friend bool operator !=(data a,data b){return !(a==b);}
friend bool operator <(data a,data b){return fabs(a.y-b.y)<eps? a.x<b.x:a.y<b.y;}
friend bool operator >(data a,data b){return !(a==b)&&!(a<b);}
friend data operator +(data a,data b){return (data){a.x+b.x,a.y+b.y};}
friend data operator -(data a,data b){return (data){a.x-b.x,a.y-b.y};}
friend double operator *(data a,data b){return a.x*b.y-a.y*b.x;}//叉积
friend double operator /(data a,data b){return a.x*b.x+a.y*b.y;}//点积
friend data operator *(data a,double b){return (data){a.x*b,a.y*b};}
}p[maxn],s[maxn],ans[4];
inline double dis(data a,data b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline bool cmp(data a,data b)
{
double t=(a-p[1])*(b-p[1]);
if (fabs(t)<eps) return (dis(a,p[1])<dis(b,p[1]));
else return t>0;
}
inline void solve()
{
F(i,2,n) if (p[i]<p[1]) swap(p[1],p[i]);
sort(p+2,p+n+1,cmp);
s[++top]=p[1];
F(i,2,n)
{
while (top>1&&(p[i]-s[top-1])*(s[top]-s[top-1])>-eps) top--;
s[++top]=p[i];
}
}
inline void getans()
{
int l=1,r=1,p=1;
double L,R,D,H;
s[0]=s[top];
F(i,0,top-1)
{
D=dis(s[i],s[i+1]);
while ((s[i+1]-s[i])*(s[p+1]-s[i])-(s[i+1]-s[i])*(s[p]-s[i])>-eps) p=(p+1)%top;
while ((s[i+1]-s[i])/(s[r+1]-s[i])-(s[i+1]-s[i])/(s[r]-s[i])>-eps) r=(r+1)%top;
if (i==0) l=r;
while ((s[i+1]-s[i])/(s[l+1]-s[i])-(s[i+1]-s[i])/(s[l]-s[i])<eps) l=(l+1)%top;
L=((s[i+1]-s[i])/(s[l]-s[i]))/D;
R=((s[i+1]-s[i])/(s[r]-s[i]))/D;
H=abs((s[i+1]-s[i])*(s[p]-s[i]))/D;
if ((R-L)*H<mn)
{
mn=(R-L)*H;
ans[0]=s[i]+(s[i+1]-s[i])*(R/D);
ans[1]=ans[0]+(s[r]-ans[0])*(H/dis(s[r],ans[0]));
ans[2]=ans[1]+(s[i]-ans[0])*((R-L)/dis(s[i],ans[0]));
ans[3]=ans[2]+(ans[0]-ans[1]);
}
}
}
int main()
{
scanf("%d",&n);
F(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
solve();
getans();
printf("%.5lf\n",mn);
int fir=0;
F(i,1,3) if (ans[i]<ans[fir]) fir=i;
F(i,0,3) printf("%.5lf %.5lf\n",ans[(i+fir)%4].x,ans[(i+fir)%4].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]最小矩形覆盖

    求出凸包后,矩形的一条边一定与凸包的某条边重合. 枚举每条边,求出离它最远的点和离它最左最右的点,因为那三个点是单调变化的,所以复杂度为$O(n)$. 注意精度. #include<cstdio ...

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

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

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

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

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

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

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

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

随机推荐

  1. 【GitHub】README.md文件中 markdown语法 插入超链接

    语法: [Spring-data-jpa 查询 复杂查询陆续完善中](http://www.cnblogs.com/sxdcgaq8080/p/7894828.html) [文本](URL) 效果:

  2. Swagger简介,轻松构造restful api的文档

    Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使 ...

  3. swift初探(供objective c开发人员參考)

    6月初的wwdc苹果推出了一门新的开发语言swift.系统10.9.3以上安装xcode6 beta版就可以体验swift. 苹果公司做了尽可能多的努力让这门语言迅速成为一个工业级的有用编程语言,而不 ...

  4. leetcode题解:Valid Parentheses(栈的应用-括号匹配)

    题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the ...

  5. 【Hadoop】Hadoop MR Job工作流引擎

    Apache Oozie 是用于 Hadoop 平台的一种工作流调度引擎.该框架(如图 1 所示)使用 Oozie 协调器促进了相互依赖的重复工作之间的协调,您可以使用预定的时间或数据可用性来触发 A ...

  6. EF使用延迟加载的本质原因

    EF(Entity Framework)是微软的一个ORM框架 使用过EF的同学都知道它有一个延迟加载的功能 那么这个延迟加载的功能到底是什么? 为什么需要延迟加载? 使用延迟加载的优点和缺点又各是什 ...

  7. Android Fragment 真正的完全解析

    出处: 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragmen ...

  8. WEB接口测试之Jmeter接口测试自动化 (二)(数据分离)

    转载:    http://www.cnblogs.com/chengtch/p/6105231.html 通过逐个录入的方式,好不容易将需要测试几十个接口的300多个测试用例录入sampler-ht ...

  9. Oracle基础 索引

    一.索引 索引是一种快速访问数据的途径,可提高数据库性能.索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需的数据,就像书的目录,可以快速查找所需的信息,无须阅读整本书. (一)索引的分类 逻 ...

  10. vue 的 起手式

    代码: vue.js // vue 起手势 (function(root,factory) { root.Vue = factory(); })(this,function(){ // 设置基础的默认 ...