[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]最小矩形覆盖 凸包+旋转卡壳
题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...
随机推荐
- Beta冲刺第七天
一.昨天的困难 没有困难. 二.今天进度 1.林洋洋:MD图片上传,修复权限问题,修复本地存储判空问题,修复协作申请没有过滤问题. 2.黄腾达:添加文件链接和邀请链接复制功能,协作树界面优化. 3.张 ...
- Beta敏捷冲刺每日报告——Day3
1.情况简述 Beta阶段Scrum Meeting 敏捷开发起止时间 2017.11.4 00:00 -- 2017.11.5 00:00 讨论时间地点 2017.11.4 晚9:30,电话会议会议 ...
- 安利给班里的大家一个chrome的GitHub插件-----gayhub
title: 一个好用的Github插件--gayhub date: 2017-09-20 15:41:36 tags: --- 别跑, 这真是正经插件. 效果, 一图流: 具体效果在项目地址很详细 ...
- JAVA_SE基础——37.main方法的详解
主函数 大家都会写吧. 大家一直都不知道为何这样设计,这样设计有什么好处呢? 白话解释: main函数的修饰符是public: 公共的 为何不用private 等等的修饰符 而规定只用public呢? ...
- ll的命令后面的字段详解
linux学习 命令ll后字段的解释 分类:linux | 标签: 命令ll后字段的解释 2010-10-25 15:47阅读(4513)评论(0) ls -l 列表信息详解 我们平时用ls -l ...
- it's a big trick
今天,正式的登上了我注册已久的博客园,最初注册园子得出发点是记录生活点滴和学习工作的心得的,那就不忘初心,从头开始吧. 从校园到工作,从东北到南方 我们毕业啦 谁说毕业遥遥无期,转眼就要各奔东西. 是 ...
- Python内置函数(49)——isinstance
英文文档: isinstance(object, classinfo) Return true if the object argument is an instance of the classin ...
- Python内置函数(10)——float
英文文档: class float([x]) Return a floating point number constructed from a number or string x. If the ...
- maven入门(1-2)settings.xml
一.简介 settings.xml对于maven来说相当于全局性的配置,用于所有的项目, 当Maven运行过程中的各种配置,例如pom.xml,不想绑定到一个固定的project或者要分配给用户时, ...
- 我的jquery validate 笔记
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF- ...