[BZOJ1185][HNOI2007]最小矩形覆盖-[凸包+旋转卡壳]
Description
Solution
感性理解一下,最小矩形一定是由一条边和凸包上的边重合的。
然后它就是模板题了。。然而真的好难调,小于大于动不动就打错。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-;
int n;
struct node{double x,y;
friend node operator +(node a,node b){return node{a.x+b.x,a.y+b.y};}
friend node operator -(node a,node b){return node{a.x-b.x,a.y-b.y};}
friend double operator *(node a,node b){return a.x*b.y-a.y*b.x;}
friend double operator /(node a,node b){return a.x*b.x+a.y*b.y;}
friend node operator *(node a,double b) {return node{a.x*b,a.y*b};}
friend bool operator <(node a,node b) { return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;}
}p[],st[],low;
double dis(node a){return a.x*a.x+a.y*a.y;}
bool cmp(node a,node b){
double t=(a-p[])*(b-p[]);
if (fabs(t)<eps) return dis(a-p[])<dis(b-p[]);
return t>;
}
int top=,now;
int main()
{
scanf("%d",&n);
low.x=low.y=;
scanf("%lf%lf",&p[].x,&p[].y);
for (int i=;i<=n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
if (p[i]<p[]) swap(p[i],p[]);
}
sort(p+,p+n+,cmp);
st[++top]=p[];
for (int i=;i<=n;i++)
{
while (top>&&(st[top]-st[top-])*(p[i]-st[top])<eps) top--;
st[++top]=p[i];
}
st[]=st[top];
node pr[];
double L,R,D,H,ans=1e10;int l=,r=,now=;
for (int i=;i<top;i++)
{
D=sqrt(dis(st[i]-st[i+]));
while ((st[i+]-st[i])*(st[now+]-st[i])>(st[i+]-st[i])*(st[now]-st[i])-eps) now=(now+)%top;
while ((st[i+]-st[i])/(st[r+]-st[i])>(st[i+]-st[i])/(st[r]-st[i])-eps) r=(r+)%top;
if (!i) l=r;
while ((st[i+]-st[i])/(st[l+]-st[i])<(st[i+]-st[i])/(st[l]-st[i])+eps) l=(l+)%top;
L=(st[i+]-st[i])/(st[l]-st[i])/D;R=(st[i+]-st[i])/(st[r]-st[i])/D;
H=abs((st[i+]-st[i])*(st[now]-st[i])/D);
if ((R-L)*H<ans)
{
ans=(R-L)*H;
pr[]=st[i]+(st[i+]-st[i])*(R/D);
pr[]=pr[]+(st[r]-pr[])*(H/sqrt(dis(pr[]-st[r])));
pr[]=pr[]-(pr[]-st[i])*((R-L)/sqrt(dis(st[i]-pr[])));
pr[]=pr[]-(pr[]-pr[]);
}
}
now=;
for (int i=;i<=;i++) if (pr[i]<pr[now]) now=i;
printf("%.5f\n",ans);
for (int i=;i<=;i++)
{
if (pr[(i+now)%].x>-*1e-) pr[(i+now)%].x=fabs(pr[(i+now)%].x);
if (pr[(i+now)%].y>-*1e-) pr[(i+now)%].y=fabs(pr[(i+now)%].y);
printf("%.5f %.5f\n",pr[(i+now)%].x,pr[(i+now)%].y);
}
}
[BZOJ1185][HNOI2007]最小矩形覆盖-[凸包+旋转卡壳]的更多相关文章
- BZOJ1185[HNOI2007] 最小矩形覆盖(旋转卡壳)
BZOJ1185[HNOI2007] 最小矩形覆盖 题面 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点的坐标 分析 首先可以先求凸包,因为覆盖了凸包上的顶点,凸 ...
- BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】
题目链接 BZOJ1185 题解 最小矩形一定有一条边在凸包上,枚举这条边,然后旋转卡壳维护另外三个端点即可 计算几何细节极多 维护另外三个端点尽量不在这条边上,意味着左端点尽量靠后,右端点尽量靠前, ...
- bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳
题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...
- 2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)
传送门 不难看出最后的矩形一定有一条边与凸包某条边重合. 因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案. 代码: #include<bits/stdc++.h> #define ...
- [HNOI2007][BZOJ1185] 最小矩形覆盖 [凸包+旋转卡壳]
题面 BZOJ题面 前置芝士 建议先学习向量相关的计算几何基础 计算几何基础戳这里 思路 用这道题学习一下凸包和旋转卡壳 首先是凸包部分 凸包 求凸包用的算法是graham算法 算法流程如下: 找到$ ...
- BZOJ1185 HNOI2007 最小矩形覆盖 凸包、旋转卡壳
传送门 首先,肯定只有凸包上的点会限制这个矩形,所以建立凸包. 然后可以知道,矩形上一定有一条边与凸包上的边重合,否则可以转一下使得它重合,答案会更小. 于是沿着凸包枚举这一条边,通过旋转卡壳找到离这 ...
- bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包
[HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 2081 Solved: 920 ...
- BZOJ1185 : [HNOI2007]最小矩形覆盖
求出凸包后,矩形的一条边一定与凸包的某条边重合. 枚举每条边,求出离它最远的点和离它最左最右的点,因为那三个点是单调变化的,所以复杂度为$O(n)$. 注意精度. #include<cstdio ...
- bzoj千题计划209:bzoj1185: [HNOI2007]最小矩形覆盖
http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解去看它 http://www.cnblogs.com/TheRoadToTheGold/p ...
随机推荐
- Java并发案例02---生产者消费者问题
package example; import java.util.LinkedList; import java.util.concurrent.TimeUnit; public class MyC ...
- 【CSS】使用浮动来创建拥有页眉、页脚、左侧目录和主体内容的首页
有两种创建水平导航栏的方法.使用行内或浮动列表项. 如果您希望链接拥有相同的尺寸,就必须使用浮动方法. 1.构建水平导航栏的方法之一是将 <li> 元素规定为行内元素: display:i ...
- linq中当生成asp.net实体模式时
linq中当生成asp.net实体模式时 注意: 选中 工具->库程序包管理器->管理解决方案的nuget程序包 选中下面的进行下载.
- python之获取文件夹下文件的绝对路径
#!/usr/bin/python #-*-conding:utf-8-*- #获取目录下文件的绝对路径 import os def getabsroute(path): listdir = os.l ...
- MongoDB简易
一 安装 1.下载 $ brew install mongodb 2.启动 $ mongod --config /usr/local/etc/mongod.conf 3.连接 $ mongo 二 ...
- DataGuard快照(snapshot)数据库
在Dataguard中,可以将standby备库切换为snapshot快照数据库,在切换为snapshot数据库后,备库将置于可读写的模式.可用于模拟业务功能测试.在使用完成之后,可以将快照数据库切换 ...
- 【Linux资源管理】iotop命令监控磁盘使用情况
一.iotop工具介绍 I/O可谓是数据库\服务器的最大瓶颈问题了,在使用top.nmon.zabbix.sar等工具监控I/O时,要么没有I/O监控(如top.zabbix),要么仅仅监控到磁盘层面 ...
- 表格中的td内的div的文字内容禁止换行一行显示的css
td { white-space: nowrap } td div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; ...
- Java之数据类型
Java数据类型分为基本数据类型和引用数据类型: 1.基本数据类型一共8种:byte,short,int, long,float,double,boolean和char; 具体可分为三类: ① 整数型 ...
- pt-archiver数据归档
可以使用percona-toolkit包中的pt-archiver工具来进行历史数据归档 pt-archiver使用的场景: 1.清理线上过期数据. 2.清理过期数据,并把数据归档到本地归档表中,或者 ...