40.凸包
凸包
定义
凸包就是把定点包在内部的,面积最小的凸多边形。
首先把所有点按照
Andrew 算法求凸包
显然,排序后最小的元素和最大的元素一定在凸包上,且从左向右看,上下凸壳的旋转方向不同,所以我们先升序枚举求出下凸壳,然后降序求出上凸壳
然后把
这个算法时间复杂度时
vector<Point> convexhull(vector<Point> p) {
int n = p.size();
sort(p.begin(), p.end(), [](Point a, Point b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
});
vector<int> ch(n * 2); int m = 0;
for (int i = 0; i < n; i++) {
while (m > 1 && cross(p[ch[m - 1]] - p[ch[m - 2]], p[i] - p[ch[m - 2]]) <= 0) m--;
ch[m++] = i;
}
for (int i = n - 2, t = m; i >= 0; i--) {
while (m > t && cross(p[ch[m - 1]] - p[ch[m - 2]], p[i] - p[ch[m - 2]]) <= 0) m--;
ch[m++] = i;
}
if (n > 1) m--;
// 这里的 p 为重新排序过了,如果返回 ch 数组想得到按顺序的值需要把原序列重新排序或者把 p 改成引用
vector<Point> res(m);
for (int i = 0; i < m; i++) res[i] = p[ch[i]];
return res;
}