题意:小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。

求个凸包,矩形的边一定在凸包上,枚举边,求最大值,即为所求,多年不拍几何,直接套了个模板

以后还得练练

 #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 包围点集最小矩形 ***的更多相关文章

  1. HDU 5251 矩形面积 (旋转卡壳)

    2015年百度之星程序设计大赛 - 初赛(1) 1006 比赛链接:2015年百度之星程序设计大赛 - 初赛(1) 题目链接:HDU 5251 Problem Description 小度熊有一个桌面 ...

  2. BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...

  3. 最小包围多边形(凸包;最小包围点集)——C代码例子

    本文来自:http://alienryderflex.com/smallest_enclosing_polygon/ 这个C代码例子需要一群2维点集,如下图所示: 要获得包含这些点的最小多边形如下图所 ...

  4. hdu5251最小矩形覆盖

    题意(中问题直接粘吧)矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少.   Input ...

  5. OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓

    本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...

  6. bzoj 1185 旋转卡壳 最小矩形覆盖

    题目大意 就是求一个最小矩形覆盖,逆时针输出其上面的点 这里可以看出,那个最小的矩形覆盖必然有一条边经过其中凸包上的两个点,另外三条边必然至少经过其中一个点,而这样的每一个点逆时针走一遍都满足单调性 ...

  7. 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1945  Solve ...

  8. BZOJ:1185: [HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 这计算几何……果然很烦…… 发现自己不会旋转卡壳,补了下,然后发现求凸包也不会…… 凸包:找一个最左下的点,其他点按照与它连边的夹角排序,然后维护一个栈用 ...

  9. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1435  Solve ...

随机推荐

  1. 2016.5.21——atoi()函数的测试

    对函数atoi()函数的测试: atoi()函数将字符串型转换为整型 代码: #include "stdafx.h" #include "iostream" # ...

  2. Html5使用history对象history.pushState()和history.replaceState()方法添加和修改浏览历史记录

    根据网上参考自己做个笔记:参考网址:http://javascript.ruanyifeng.com/bom/history.html history.pushState() HTML5为histor ...

  3. springCloud全实战超详细代码demo+笔记

    码云: https://gitee.com/houzheng1216/springcloud

  4. weight decay(权值衰减)、momentum(冲量)和normalization

    一.weight decay(权值衰减)的使用既不是为了提高你所说的收敛精确度也不是为了提高收敛速度,其最终目的是防止过拟合.在损失函数中,weight decay是放在正则项(regularizat ...

  5. Python标准库笔记(10) — itertools模块

    itertools 用于更高效地创建迭代器的函数工具. itertools 提供的功能受Clojure,Haskell,APL和SML等函数式编程语言的类似功能的启发.它们的目的是快速有效地使用内存, ...

  6. 跳出python的各种坑(1)

    2017-11-1915:38:17 一定要跳出python的各种坑,一开始遇到的好多思维上的认知错误,因为刚开始学习,对python是个什么都不清楚,所以记录一下自己遇到的各种坑.不用担心自己遇到的 ...

  7. MySQL分布式集群之MyCAT(三)rule的分析【转】

    首先写在最前面,MyCAT1.4的alpha版本已经发布了,这里面修复了不少的bug,也完善了一细节,之前两篇博客已经做了一些修改 ---------------------------------- ...

  8. Fiddler是最强大最好用的Web调试工具

    Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说,都有很大 ...

  9. 【不知道是啥的NOIP模拟赛】网络入侵

    题意是这样的: 给你一棵树,每个边有一个初始的0/1边权.你希望把它弄成一个给定的样子. 你每次可以选一条树链取反,然后问你最少要操作几次. ----------------------------- ...

  10. 【前端开发】前端引入公共部分footer header的几种方法,及iframe自适应高度js

    一.引入页面几种方法   1.IFrame引入,看看下面的代码    <iframe   frameborder=0   border=0   width=300   height=300    ...