计算几何
@
凸包
1.定义:给定一些点,求能把所有这些点包含在内的面积最小的多边形,如果是凸多边形则称为凸包;
2.解决方法:
一是 : Graham扫描法 O(nlogn)
二是 : Jarvis步进法 O(nh) h是凸包上的顶点数
基本思路 : "旋转扫除",设定一个参照顶点,逐个旋转到其他顶点,并判断这些顶点是否在凸包上
3.模板代码:
Graham扫描法的变种Andrew算法(更快更稳)
算法做两次扫描,先从最左边的点沿下凸包扫描到最右边,再从最右边的点扫描上凸包扫描到最左边;上凸包和下凸包连起来就是完整的凸包;
具体步骤 :
1 . 将所有点按照横坐标x从小到大进行排序,如果x相同,按y从小到大排序,并且删除重复的点;得到序列{p0,p1,p2,p3....pm}
2 . 从左到右扫描所有点,求下凸包;p0一定在凸包上,是最左边的顶点;然后依次检查{p1,p2,p3....pm},扩展出下凸包;
判断依据 : 如果新点在凸包前进方向的左边,说明在下凸包上,把它加入到凸包;如果在右边,说明拐弯了,删除最后加入凸包的点,继续这个过程,知道检查完所有点;
是否拐弯 : 利用叉积判断(插图)
3 . 从右到左重新扫描所有点求上凸包;
O(nlogn)
4.例题:
hdu 1392 "Surround the Trees"
全解查看博客题解偏
https://blog.csdn.net/gpc_123/article/details/122741291
int Convex_hull(Point *p,int n,Point *ch){
sort(p, p + n);//对点排序
n = unique(p, p + n) - p;//去重
int v = 0;
//求下凸包,如果p[i]是右拐弯,这个点不在凸包上往回退
for (int i = 0; i < n;i ++){
while(v > 1 && sgn(Cross(ch[v - 1] - ch[v - 2],p[i] - ch[v - 2])) <= 0)
v--;
ch[v++] = p[i];
}
int j = v;
//求上凸包
for (int i = n - 2; i >= 0;i --){
while(v > j && sgn(Cross(ch[v - 1] - ch[v - 2],p[i] - ch[v - 2])) <= 0)
v--;
ch[v++] = p[i];
}
if(n > 1) v--;
return v; //返回凸包顶点数
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理