[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 ...
随机推荐
- - (void)addConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints
Adds multiple constraints on the layout of the receiving view or its subviews. All constraints mus ...
- 2456. mode【乱搞】
Description 给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数. Input 第1行一个正整数n. 第2行n个正整数用空格隔开. Output 一行一个正整数 ...
- luogu P2015 二叉苹果树
嘟嘟嘟 这应该算一道树形背包吧,虽然我还是分不太清树形背包和树形dp的区别…… 首先dp[i][u][j] 表示在u的前 i 棵子树中,留了 j 条树枝时最大的苹果数量,而且根据题目描述,这些留下的树 ...
- 解决windows7无法连接CentOS7系统中oracle问题:ORA-12514 TNS 监听程序当前无法识别
linux开启后终端按下面输入(容易忘记,记录下): [oracle@localhost ~]$ lsnrctl stop #先关闭监听服务 [oracle@localh ...
- Python 模块化 import 语句介绍(一)
用法: import 模块1[,模块2,模块3...] os 顶级模块os.path 非顶级模块as 相当于重命名 import 的本质: 解释器负责模块单独加载,单独初始化,生成一个模块对象,当前作 ...
- disconf实践(一)Ubuntu16.04部署disconf
在企业中,随着公司业务的扩张,用户量的增大,单一节点应用无法支撑正常的业务逻辑,比较常见的现象是访问速度变慢,甚至超时,严重时可能会造成系统宕机.为了尽量减少宕机的风险,单一节点系统需要进行水平扩展, ...
- CSS网页布局:盒子模型
一.盒子模型 标准盒子模型(W3C盒子) 不论是标准盒模型还是IE盒子模型,都有content.padding.border.margin四个部分组成,但从上图也可以看出W3C盒子和IE盒子主要区别在 ...
- CSP 试题编号201803-2 Java实现
package HB; import java.util.Scanner; public class Test_06 { public static void main(String[] args) ...
- 工具 | Axure基础操作 No.6
这个是基础教程最后一篇,但是这仅仅是个开始,需要学的东西还有很多.坚持! 1.生成部分原型页面 不能单独生成子级的页面,会自动的勾选上父级.如果想单独的生成的话,就得把这个页面的级别提高,变成一级页面 ...
- Objective-C 方法交换实践(三) - Aspects 源码解析
一.类与变量 AspectOptions typedef NS_OPTIONS(NSUInteger, AspectOptions) { AspectPositionAfter = 0, /// 原方 ...