[HNOI2007]最小矩形覆盖
题目描述
给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点坐标
输入输出格式
输入格式:
第一行为一个整数n(3<=n<=50000),从第2至第n+1行每行有两个浮点数,表示一个顶点的x和y坐标,不用科学计数法
输出格式:
第一行为一个浮点数,表示所求矩形的面积(精确到小数点后5位),接下来4行每行表示一个顶点坐标,要求第一行为y坐标最小的顶点,其后按逆时针输出顶点坐标.如果用相同y坐标,先输出最小x坐标的顶点
输入输出样例
6
1.0 3.00000
1 4.00000
2.0000 1
3 0.0000
3.00000 6
6.0 3.0
18.00000
3.00000 0.00000
6.00000 3.00000
3.00000 6.00000
0.00000 3.00000
最小的覆盖矩形肯定有边在凸包上
先求出凸包,然后枚举凸包上的边为直线构造矩形
用单调栈求出离该直线最远的点,左边最远的点和右边最远的点
就可以算出矩形的四个点
有可能输出-0.0000,所以要特判
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long double ld;
struct point
{
ld x,y;
}p[],s[];
point ansp[];
ld eps=1e-,res,ans;
int n,top;
ld cross(point a,point b)
{
return a.x*b.y-b.x*a.y;
}
point operator *(point a,double b)
{
return (point){a.x*b,a.y*b};
}
point operator -(point a,point b)
{
return (point){a.x-b.x,a.y-b.y};
}
point operator +(point a,point b)
{
return (point){a.x+b.x,a.y+b.y};
}
ld dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
ld dist(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
int dcmp(ld x)
{
if (x<-eps) return -;
if (x>eps) return ;
return ;
}
bool cmp(point a,point b)
{
return (a.y<b.y)||(a.y==b.y&&a.x<b.x);
}
bool cmp2(point a,point b)
{
int t=dcmp(cross((p[]-a),(p[]-b)));
if (t==) return dist(p[]-a)<dist(p[]-b);
return t>;
}
bool cmp3(point a,point b)
{
return atan2(a.y-ansp[].y,a.x-ansp[].x)<atan2(b.y-ansp[].y,b.x-ansp[].x);
}
void graham()
{int i;
sort(p+,p+n+,cmp);
sort(p+,p+n+,cmp2);
s[++top]=p[];s[++top]=p[];
for (i=;i<=n;i++)
{
while (top>&&dcmp(cross((p[i]-s[top-]),(s[top]-s[top-])))>=) top--;
s[++top]=p[i];
}
}
void solve()
{int i;
int pos=,r=,l;
s[top+]=s[];
for (i=;i<=top;i++)
{
ld D=dist(s[i+]-s[i]);
while (dcmp(cross((s[i+]-s[i]),(s[pos+]-s[i]))-cross((s[i+]-s[i]),(s[pos]-s[i])))>) pos=pos%top+;
while (dcmp(dot(s[i+]-s[i],s[r+]-s[i])-dot(s[i+]-s[i],s[r]-s[i]))>=) r=r%top+;
if (i==) l=r;
while (dcmp(dot(s[i+]-s[i],s[l+]-s[i])-dot(s[i+]-s[i],s[l]-s[i]))<=) l=l%top+;
ld L=dot(s[l]-s[i],s[i+]-s[i])/D;
ld R=dot(s[i+]-s[i],s[r]-s[i])/D;
ld H=cross((s[i+]-s[i]),(s[pos]-s[i]))/D;
res=(R-L)*H;if (res<) res=-res;
if (dcmp(res-ans)<)
{
ans=res;
ansp[]=s[i]+(s[i+]-s[i])*(L/D);
ansp[]=s[i]+(s[i+]-s[i])*(R/D);
ansp[]=ansp[]+(s[l]-ansp[])*(H/dist(s[l]-ansp[]));
ansp[]=ansp[]+(s[r]-ansp[])*(H/dist(s[r]-ansp[]));
if (dcmp(ansp[].x)==) ansp[].x=fabs(ansp[].x);
if (dcmp(ansp[].y)==) ansp[].y=fabs(ansp[].y);
if (dcmp(ansp[].x)==) ansp[].x=fabs(ansp[].x);
if (dcmp(ansp[].y)==) ansp[].y=fabs(ansp[].y);
if (dcmp(ansp[].x)==) ansp[].x=fabs(ansp[].x);
if (dcmp(ansp[].y)==) ansp[].y=fabs(ansp[].y);
if (dcmp(ansp[].x)==) ansp[].x=fabs(ansp[].x);
if (dcmp(ansp[].y)==) ansp[].y=fabs(ansp[].y);
}
}
}
int main()
{int i;
cin>>n;
ans=2e9;
for (i=;i<=n;i++)
{
scanf("%Lf%Lf",&p[i].x,&p[i].y);
}
graham();
solve();
printf("%.5Lf\n",ans);
sort(ansp+,ansp+,cmp);
sort(ansp+,ansp+,cmp3);
for (i=;i<=;i++)
printf("%.5Lf %.5Lf\n",ansp[i].x,ansp[i].y);
}
[HNOI2007]最小矩形覆盖的更多相关文章
- 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1945 Solve ...
- BZOJ:1185: [HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 这计算几何……果然很烦…… 发现自己不会旋转卡壳,补了下,然后发现求凸包也不会…… 凸包:找一个最左下的点,其他点按照与它连边的夹角排序,然后维护一个栈用 ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1435 Solve ...
- 【BZOJ1185】[HNOI2007]最小矩形覆盖(凸包,旋转卡壳)
[BZOJ1185][HNOI2007]最小矩形覆盖(凸包,旋转卡壳) 题面 BZOJ 洛谷 题解 最小的矩形一定存在一条边在凸包上,那么枚举这条边,我们还差三个点,即距离当前边的最远点,以及做这条边 ...
- bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包
[HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 2081 Solved: 920 ...
- 1185: [HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1426 Solve ...
- BZOJ1185[HNOI2007] 最小矩形覆盖(旋转卡壳)
BZOJ1185[HNOI2007] 最小矩形覆盖 题面 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点的坐标 分析 首先可以先求凸包,因为覆盖了凸包上的顶点,凸 ...
- 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)
题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...
- LG3187 [HNOI2007]最小矩形覆盖
题意 题目描述 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点坐标 输入输出格式 输入格式: 第一行为一个整数n(3<=n<=50000),从第2至第 ...
- bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳
题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...
随机推荐
- windows环境下,apache虚拟主机配置
在windows环境下,apache从配置文件的相关配置: Windows 是市场占有率最高的 PC 操作系统, 也是很多人的开发环境. 其 VirtualHost 配置方法与 Linux 上有些差异 ...
- Alpha第一天
Alpha第一天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...
- 学号:201621123032 《Java程序设计》第2周学习总结
1: 本周学习总结 本周学习java的数据类型,两种数据类型:基本数据类型和引用数据类型. 学习关于String和StringBuilder之间不同. 本周还学习数组.一维数组,多维数组,和动态数组. ...
- splinter web测试框架
1.安装谷歌浏览器驱动(windows把驱动解压放在Python.exe同级目录即可) http://chromedriver.storage.googleapis.com/index.html 注意 ...
- android 自定义ScrollView实现背景图片伸缩(阻尼效果)
android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...
- 从Nest到Nesk -- 模块化Node框架的实践
文: 达孚(沪江Web前端架构师) 本文原创,转至沪江技术 首先上一下项目地址(:>): Nest:https://github.com/nestjs/nest Nesk:https://git ...
- LeetCode & Q26-Remove Duplicates from Sorted Array-Easy
Descriptions: Given a sorted array, remove the duplicates in place such that each element appear onl ...
- 剑指offer-数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- python 单例模式的四种创建方式
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- maven常见问题处理(3-4)配置代理服务器
有的公司基于安全因素考虑,要求员工使用通过安全认证的代理访问因特网. 这时就需要为Maven配置HTTP代理. 在目录~/.m2/setting.xml文件中编辑如下(如果没有该文件,则复制$M2_H ...