题意:给出n个矩形,求能覆盖所有矩形的最小的矩形的面积。
题解:对所有点求凸包,然后旋转卡壳,对没一条边求该边的最左最右和最上的三个点。
   利用叉积面积求高,利用点积的性质求最左右点和长度,更新面积最小值即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define MAX 50010
using namespace std;
struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y){}
};
Point P[MAX],ch[MAX];
typedef Point Vector;
typedef Point point;
Vector operator - (Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
bool operator <(const Point &a,const Point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double eps=1e-;
int dcmp(double x)
{
if(fabs(x)<eps) return ; else return x<?-:;
}
bool operator ==(const Point &a,const Point &b)
{
return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
double dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}
int ConvexHull(Point *p,int n)
{
sort(p,p+n);
n=unique(p,p+n)-p;
int m=;
for(int i=;i<n;i++)
{
while(m>&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--)
{
while(m>k&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
if(n>) m--;
return m;
}
double Length(Vector A)
{
return dot(A,A);
}
double rotating_calipers(Point *p,int n)
{
int l=,r=,w;
double ans=1e30;
p[n]=p[];
for(int i=;i<n;i++)
{
//注意这里等于0一定要算上
//这里debug了整整一个小时 - -|||||
//找到至高点
while(dcmp(Cross(p[i+]-p[i],p[w+]-p[i])-Cross(p[i+]-p[i],p[w]-p[i]))>=) //因为边平行的时候面积相等 虽然如此但还是要继续找下一个 横着爬不动的意思
w=(w+)%n;
//找到最右的点 不可能向左的
while(dcmp(dot(p[i+]-p[i],p[r+]-p[i])-dot(p[i+]-p[i],p[r]-p[i]))>) //凸包不可能凹进去 所以不需要等号 加深对凸包求解过程的理解
r=(r+)%n;
if(i==) l=r;
while(dcmp(dot(p[i+]-p[i],p[l+]-p[i])-dot(p[i+]-p[i],p[l]-p[i]))<=) //必须加等号 否则凸包遇到直边的时候拐不过来 上不去 第二组样例可以完美说明问题
l=(l+)%n;
double d=Length(p[i+]-p[i]);
double area=fabs(Cross(p[i+]-p[i],p[w]-p[i]))
*fabs(dot(p[i+]-p[i],p[r]-p[i])-dot(p[i+]-p[i],p[l]-p[i]))/d;
//cout<<fabs(Cross(p[i+1]-p[i],p[w]-p[i]))<<" "; 这里灵活运用点积求底边长度 上面那一整行化简后就是底边长度
//cout<<"rrrrr "<<r<<" lll "<<l<<endl;
//cout<<dot(p[i+1]-p[i],p[r]-p[i])<<" "<<dot(p[i+1]-p[i],p[l]-p[i])<<endl;
ans=min(ans,area);
}
return ans;
}
int main()
{
int t,n,cas=;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
n*=;
for(int i=;i<n;i++)
scanf("%lf%lf",&P[i].x,&P[i].y);
int m=ConvexHull(P,n);
//for(int i=0;i<n;i++)
//cout<<ch[i].x<<" "<<ch[i].y<<endl;
double ans;
if(m<) ans=;
else ans=rotating_calipers(ch,m);
long long tmp = ans+0.5;
printf("Case #%d:\n%lld\n",cas++,tmp);
}
return ;
}

分析过程:

HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛 - 初赛(1)的更多相关文章

  1. hdu 5253 连接的管道(kruskal)(2015年百度之星程序设计大赛 - 初赛(2))

    连接的管道 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  2. poj 2079 Triangle (二维凸包旋转卡壳)

    Triangle Time Limit: 3000MS   Memory Limit: 30000KB   64bit IO Format: %I64d & %I64u Submit Stat ...

  3. poj 2187 Beauty Contest(二维凸包旋转卡壳)

    D - Beauty Contest Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  4. HDU 6119 小小粉丝度度熊 【预处理+尺取法】(2017"百度之星"程序设计大赛 - 初赛(B))

    小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. HDU 6114 Chess 【组合数】(2017"百度之星"程序设计大赛 - 初赛(B))

    Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. 2019 年百度之星·程序设计大赛 - 初赛一 C. HDU 6670 Mindis 离散化+dijkstra

    题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6670 Mindis Time Limit: 4000/2000 MS (Java/Others) M ...

  7. HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. HDU 6109 数据分割 【并查集+set】 (2017"百度之星"程序设计大赛 - 初赛(A))

    数据分割 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 6108 小C的倍数问题 【数学】 (2017"百度之星"程序设计大赛 - 初赛(A))

    小C的倍数问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

随机推荐

  1. SGU 169 numbers 数学

    169.Numbers Let us call P(n) - the product of all digits of number n (in decimal notation). For exam ...

  2. linux-shell——04

    mv 移动文件或者目录 格式:mv [选项]      源文件/目录     目标文件/目录 注:若移动目标位置与源位置相同(当前下操作),则此操作相当于重命名(改名) ex: [root@local ...

  3. 寻找物体的凸包 opencv

    凸包的含义: 在二维平面上给定点集,凸包就是将最外层的点连接起来构成的凸多边形.并且这个凸多边形能包含点集中所有的点.OPENCV中: convexHull函数用于寻找图像点集中的凸包.它有六个输入参 ...

  4. Ubuntu下配置LAMP + PhpStorm

    本文仅作为一个记录,以下配置在Ubuntu 14.10 64-bit上验证通过. 安装Apache 2:sudo apt-get install apache2 安装成功能够后,通过浏览器访问loca ...

  5. salt demo 环境

    demo 环境 安装 virtualBox和vagrant 安装工具包:virtualBox, vagrant 下载 https://github.com/UtahDave/salt-vagrant- ...

  6. 18 Django-组件拾遗

    一 Django的form组件 forms组件 二 Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的 ...

  7. 9.3centos7安装python3 以及tab补全功能

    1.安装python3 1.1下载python源码包 网址:https://www.python.org/downloads/release/python-362/ 下载地址:https://www. ...

  8. 《算法》C++代码 Dijkstra

    单源最短路,复杂度是O(N²),堆优化的是O(NlogN).基本思想是贪心,每次都加入一个当前最近的点,可以证明每次当时最近的点就是当前最短的路径.因此,所有点都加入之后,起点到所有点的最短路径就都求 ...

  9. linux部署环境配置

    https://blog.csdn.net/dsczxcc/article/details/78728330

  10. msql 数据库介绍和启动

    什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但 ...