hdu 5251 包围点集最小矩形 ***
题意:小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。
求个凸包,矩形的边一定在凸包上,枚举边,求最大值,即为所求,多年不拍几何,直接套了个模板
以后还得练练
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
typedef double typev;
const double eps = 1e-;
const int N = ;
int sign(double d){
return d < -eps ? - : (d > eps);
}
struct point{
typev x, y;
void in()
{
scanf("%lf%lf",&x,&y);
}
point operator-(point d){
point dd;
dd.x = this->x - d.x;
dd.y = this->y - d.y;
return dd;
}
point operator+(point d){
point dd;
dd.x = this->x + d.x;
dd.y = this->y + d.y;
return dd;
}
void read(){ scanf("%lf%lf", &x, &y); }
}ps[N],pd[N];
int n, cn;
double dist(point d1, point d2){
return sqrt(pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0));
}
double dist2(point d1, point d2){
return pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0);
}
bool cmp(point d1, point d2){
return d1.y < d2.y || (d1.y == d2.y && d1.x < d2.x);
}
//st1-->ed1叉乘st2-->ed2的值
typev xmul(point st1, point ed1, point st2, point ed2){
return (ed1.x - st1.x) * (ed2.y - st2.y) - (ed1.y - st1.y) * (ed2.x - st2.x);
}
typev dmul(point st1, point ed1, point st2, point ed2){
return (ed1.x - st1.x) * (ed2.x - st2.x) + (ed1.y - st1.y) * (ed2.y - st2.y);
}
//多边形类
struct poly{
static const int N = ; //点数的最大值
point ps[N+]; //逆时针存储多边形的点,[0,pn-1]存储点
int pn; //点数
poly() { pn = ; }
//加进一个点
void push(point tp){
ps[pn++] = tp;
}
//第k个位置
int trim(int k){
return (k+pn)%pn;
}
void clear(){ pn = ; }
};
//返回含有n个点的点集ps的凸包
poly graham(point* ps, int n){
sort(ps, ps + n, cmp);
poly ans;
if(n <= ){
for(int i = ; i < n; i++){
ans.push(ps[i]);
}
return ans;
}
ans.push(ps[]);
ans.push(ps[]);
point* tps = ans.ps;
int top = -;
tps[++top] = ps[];
tps[++top] = ps[];
for(int i = ; i < n; i++){
while(top > && xmul(tps[top - ], tps[top], tps[top - ], ps[i]) <= ) top--;
tps[++top] = ps[i];
}
int tmp = top; //注意要赋值给tmp!
for(int i = n - ; i >= ; i--){
while(top > tmp && xmul(tps[top - ], tps[top], tps[top - ], ps[i]) <= ) top--;
tps[++top] = ps[i];
}
ans.pn = top;
return ans;
}
//求点p到st->ed的垂足,列参数方程
point getRoot(point p, point st, point ed){
point ans;
double u=((ed.x-st.x)*(ed.x-st.x)+(ed.y-st.y)*(ed.y-st.y));
u = ((ed.x-st.x)*(ed.x-p.x)+(ed.y-st.y)*(ed.y-p.y))/u;
ans.x = u*st.x+(-u)*ed.x;
ans.y = u*st.y+(-u)*ed.y;
return ans;
}
//next为直线(st,ed)上的点,返回next沿(st,ed)右手垂直方向延伸l之后的点
point change(point st, point ed, point next, double l){
point dd;
dd.x = -(ed - st).y;
dd.y = (ed - st).x;
double len = sqrt(dd.x * dd.x + dd.y * dd.y);
dd.x /= len, dd.y /= len;
dd.x *= l, dd.y *= l;
dd = dd + next;
return dd;
}
//求含n个点的点集ps的最小面积矩形,并把结果放在ds(ds为一个长度是4的数组即可,ds中的点是逆时针的)中,并返回这个最小面积。
double getMinAreaRect(point* ps, int n, point* ds){
int cn, i;
double ans;
point* con;
poly tpoly = graham(ps, n);
con = tpoly.ps;
cn = tpoly.pn;
if(cn <= ){
ds[] = con[]; ds[] = con[];
ds[] = con[]; ds[] = con[];
ans=;
}else{
int l, r, u;
double tmp, len;
con[cn] = con[];
ans = 1e40;
l = i = ;
while(dmul(con[i], con[i+], con[i], con[l])
>= dmul(con[i], con[i+], con[i], con[(l-+cn)%cn])){
l = (l-+cn)%cn;
}
for(r=u=i = ; i < cn; i++){
while(xmul(con[i], con[i+], con[i], con[u])
<= xmul(con[i], con[i+], con[i], con[(u+)%cn])){
u = (u+)%cn;
}
while(dmul(con[i], con[i+], con[i], con[r])
<= dmul(con[i], con[i+], con[i], con[(r+)%cn])){
r = (r+)%cn;
}
while(dmul(con[i], con[i+], con[i], con[l])
>= dmul(con[i], con[i+], con[i], con[(l+)%cn])){
l = (l+)%cn;
}
tmp = dmul(con[i], con[i+], con[i], con[r]) - dmul(con[i], con[i+], con[i], con[l]);
tmp *= xmul(con[i], con[i+], con[i], con[u]);
tmp /= dist2(con[i], con[i+]);
len = xmul(con[i], con[i+], con[i], con[u])/dist(con[i], con[i+]);
if(sign(tmp - ans) < ){
ans = tmp;
ds[] = getRoot(con[l], con[i], con[i+]);
ds[] = getRoot(con[r], con[i+], con[i]);
ds[] = change(con[i], con[i+], ds[], len);
ds[] = change(con[i], con[i+], ds[], len);
}
}
}
return ans+eps;
}
int main()
{
int i,j,k;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
int tt;
scanf("%d",&tt);
int ca=;
while(tt--)
{
printf("Case #%d:\n",ca++);
scanf("%d",&n);
for(i=;i<*n;i++)
{
ps[i].in();
}
double q=getMinAreaRect(ps,*n,pd);
printf("%d\n",int(q+0.5));
}
}
hdu 5251 包围点集最小矩形 ***的更多相关文章
- HDU 5251 矩形面积 (旋转卡壳)
2015年百度之星程序设计大赛 - 初赛(1) 1006 比赛链接:2015年百度之星程序设计大赛 - 初赛(1) 题目链接:HDU 5251 Problem Description 小度熊有一个桌面 ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子
来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...
- 最小包围多边形(凸包;最小包围点集)——C代码例子
本文来自:http://alienryderflex.com/smallest_enclosing_polygon/ 这个C代码例子需要一群2维点集,如下图所示: 要获得包含这些点的最小多边形如下图所 ...
- hdu5251最小矩形覆盖
题意(中问题直接粘吧)矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input ...
- OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓
本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...
- bzoj 1185 旋转卡壳 最小矩形覆盖
题目大意 就是求一个最小矩形覆盖,逆时针输出其上面的点 这里可以看出,那个最小的矩形覆盖必然有一条边经过其中凸包上的两个点,另外三条边必然至少经过其中一个点,而这样的每一个点逆时针走一遍都满足单调性 ...
- 【旋转卡壳+凸包】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 ...
随机推荐
- 2016.5.16——leetcode:Reverse Bits(超详细讲解)
leetcode:Reverse Bits 本题目收获 移位(<< >>), 或(|),与(&)计算的妙用 题目: Reverse bits of a given 3 ...
- JDK1.8源码LinkedList
引用博文链接 : https://www.cnblogs.com/leskang/p/6029780.html LinkedList继承了 AbstractSequentialList抽象类,而不是像 ...
- JDk1.8源码StringBuffer
一.概念 StringBuffer A thread-safe, mutable sequence of characters. A string buffer is like a {@link St ...
- Esper复杂事务处理一小时入门
来自小韩 什么是Esper 想要认识Esper,先要了解CEP(Complex Event Processing),到处都有,并且各方理解也有偏差,我就不赘述了. Esper就是CEP的一个java的 ...
- Docker技术这些应用场景【转】
场景一:节省项目环境部署时间 1.单项目打包 每次部署项目到测试.生产等环境,都要部署一大堆依赖的软件.工具,而且部署期间出现问题几率很大,不经意就花费了很长时间. Docker主要理念就是环境打包部 ...
- 一张图教会CSS3倒影
分享 示例图片 在CSS3之前,想要实现示例图片这样的一个倒影效果一般只能通过处理图片的方式,而CSS3问世之后,想要实现这样的效果变得非常简单,只需一个CSS3属性就可以轻松实现了. 这就是今天所要 ...
- 排序算法——Shell排序
二.Shell排序 Shell排序也叫“缩减增量排序”(disminishing increment sort),基于插入排序进行. Shell建议的序列是一种常用但不理想的增量序列:1,...,N/ ...
- mac idea内存溢出
VM options: -mx2048m -XX:MaxPermSize=2048m -Drebel.spring_plugin=true -Drebel.hibernate_plugin=true
- set,list,map分析
想了下集合,列表,映射三者关系 set,list,map ArrayList采用数组方式存储数据,继承List; LinkedList采用链表方式存储数据,继承List; 所以数组方式都有下表,以及每 ...
- 洛谷P2261余数求和
传送门啦 再一次见证了分块的神奇用法,在数论里用分块思想. 我们要求 $ ans = \sum\limits ^{n} _{i=1} (k % i) $ ,如果我没看错,这个题的暴力有 $ 60 $ ...