bzoj 1185 最小矩形覆盖 —— 旋转卡壳
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1185
枚举一条边,维护上、左、右方的点;
上方点到这条边距离最远,所以用叉积求面积维护;
左右点到这条边的射影最长(!),所以用点积求射影维护;
因为维护的点是只能逆时针走的,所以初始的左边点要特殊处理一下,其实等于右边点即可,然后可以走过去到合适位置;
然后维护矩形的四个端点,就是根据距离,从边的端点走过去,还挺有意思的;
注意不要输出 -0;
然而这其实是假的呵呵,Narh 一拍就出错了,还是很小的数据很明显的错囧
只是不知道哪里错,怎么调...
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double db;
db const eps=1e-;
int const xn=;
int n;
db ans;
int dmp(db x){if(fabs(x)<=eps)return ; return x>eps?:-;}
struct P{
db x,y;
P(db x=,db y=):x(x),y(y) {}
bool operator < (const P &b) const
{return dmp(x-b.x)<||dmp(x-b.x)==&&dmp(y-b.y)<;}
P operator + (const P &b) const
{return P(x+b.x,y+b.y);}
P operator - (const P &b) const
{return P(x-b.x,y-b.y);}
P operator * (const db &v) const
{return P(x*v,y*v);}
P operator / (const db &v) const
{return P(x/v,y/v);}
}p[xn],c[xn],pos[];
db cross(P a,P b){return a.x*b.y-a.y*b.x;}
db dot(P a,P b){return a.x*b.x+a.y*b.y;}
void find()
{
sort(p+,p+n+); int top=;
for(int i=;i<=n;i++)
{
while(top>&&dmp(cross(c[top]-c[top-],p[i]-c[top]))<=)top--;
c[++top]=p[i];
}
int num=top;
for(int i=n-;i;i--)
{
while(top>num&&dmp(cross(c[top]-c[top-],p[i]-c[top]))<=)top--;
c[++top]=p[i];
}
n=top-;
}
int upt(int x){if(x>n)x-=n; if(x<)x+=n; return x;}
db sqr(db x){return x*x;}
db dis(P a,P b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
bool cmp(P a,P b){return dmp(a.y-b.y)<||(dmp(a.y-b.y)==&&dmp(a.x-b.x)<);}
void rc()
{
ans=-;
//int p=2,l=1,r=2;//
int p=,l=,r=; c[n+]=c[];
for(int i=;i<=n;i++)
{
db d=dis(c[i],c[i+]);
while(dmp(cross(c[i]-c[p],c[i+]-c[p])-cross(c[i]-c[p+],c[i+]-c[p+]))<=)p=upt(p+);
while(dmp(dot(c[r]-c[i],c[i+]-c[i])-dot(c[r+]-c[i],c[i+]-c[i]))<=)r=upt(r+);
if(i==)l=r;//
while(dmp(dot(c[l]-c[i],c[i+]-c[i])-dot(c[l+]-c[i],c[i+]-c[i]))>=)l=upt(l+);
db L=dot(c[i+]-c[i],c[l]-c[i])/d;
db R=dot(c[i+]-c[i],c[r]-c[i])/d;
db H=cross(c[i]-c[p],c[i+]-c[p])/d;
db tmp=(R-L)*H;
if(ans<||dmp(ans-tmp)>)
{
ans=tmp;
pos[]=c[i]+(c[i+]-c[i])*(R/d);
pos[]=pos[]+(c[r]-pos[])*(H/dis(c[r],pos[]));
//pos[2]=pos[1]+(c[p]-pos[1])*((R-L)/dis(c[p],pos[1]));//也可
pos[]=pos[]+(c[i]-pos[])*((R-L)/dis(c[i],pos[]));
pos[]=pos[]+(pos[]-pos[]);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
find();
rc();
printf("%.5f\n",ans);
int st=;
for(int i=;i<;i++)if(cmp(pos[i],pos[st]))st=i;
for(int i=st,cnt=;cnt<=;i=(i+)%,cnt++)
{
if(fabs(pos[i].x)<=eps)pos[i].x=;
if(fabs(pos[i].y)<=eps)pos[i].y=;
printf("%.5f %.5f\n",pos[i].x,pos[i].y);
}
return ;
}
bzoj 1185 最小矩形覆盖 —— 旋转卡壳的更多相关文章
- 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)
题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1435 Solve ...
- bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包
[HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 2081 Solved: 920 ...
- bzoj 1185 [HNOI2007]最小矩形覆盖——旋转卡壳
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 矩形一定贴着凸包的一条边.不过只是感觉这样. 枚举一条边,对面的点就是正常的旋转卡壳. ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子
来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...
- 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)
给你一些点,让你用最小的矩形覆盖这些点 首先有一个结论,矩形的一条边一定在凸包上!!! 枚举凸包上的边 用旋转卡壳在凸包上找矩形另外三点... 注意精度问题 #include<cstdio> ...
- BZOJ 1185 最小矩形覆盖
Description Input Output Sample Input Sample Output HINT 其实这题就是一道旋转卡壳的裸题,但是我的精度萎了.直接上hzwer的代码吧... #i ...
- HDU 5251 矩形面积 (旋转卡壳)
2015年百度之星程序设计大赛 - 初赛(1) 1006 比赛链接:2015年百度之星程序设计大赛 - 初赛(1) 题目链接:HDU 5251 Problem Description 小度熊有一个桌面 ...
- bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳
题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...
随机推荐
- java并发编程基础---Sky
1.线程及启动和终止 1.1 线程 -进程/优先级 操作系统调度的最小单元是线程,线程是轻量级进程. 线程优先级由setPriority(int)方法来设置,默认优先级是5,等级1~10.等级越高分的 ...
- json-lib-2.5-jdk.jar 需要依赖的jar包
commons-lang3-3.1.jar commons-lang-2.5.jar ezmorph-1.0.6.jar commons-collections-3.2.1.jar commons-b ...
- 为什么Git 比 SVN 好
原文链接:http://www.worldhello.net/2012/04/12/why-git-is-better-than-svn.html Why Git is better than SVN ...
- nc传文件
nc传文件 先启动接收方 nc -l -p 9999 > index.lua 后启动发送方 nc 192.168.1.1 9999 < index.lua
- 【logback】认识logback
一. Reference:http://www.cnblogs.com/yongze103/archive/2012/05/05/2484753.html 1. Logback为取代log4j而生,l ...
- js 动态加载事件的几种方法总结
本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添 ...
- redis于spring整合之RedisTemplate
原文地址: http://www.jianshu.com/p/7bf5dc61ca06
- 创建图形用户界面GUI和事件监听机制的简单实现(java)
创建图形化界面 1.创建Frame窗体 2.对窗体进行基本设置 比如:大小.位置.布局 3.定义组件 4.将组建通过窗体添加到窗体中 5.让窗体显示,通过setVisib ...
- [原创]java WEB学习笔记13:JSP介绍(背景,特点,原理)
JSP介绍:(理解) 1)JSP背景 ①在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变: ②如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的静态 ...
- 【leetcode刷题笔记】Search in Rotated Sorted Array II
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...