(v4 更新)0x70 计算几何

0x72 计算几何 II

凸包

当插入的点 \(x\) 坐标单调时(不论递增还是递减),由于仅涉及凸壳尾部的修改,可以使用 std::vector 维护凸壳。

查询答案时,在凸壳上二分求峰值。

0x72 凸壳.cpp

// 检测连续三个点的凸性(大于 0 下凸,小于 0 上凸)
bool check(point a, point b, point c) {
    return i128(b.x - a.x) * (c.y - a.y) - i128(c.x - a.x) * (b.y - a.y) > 0; // 若要求下凸壳,改成 <
}

// 求凸壳(默认:上凸壳)
auto gethull(std::vector<point> seq) {
    std::sort(seq.begin(), seq.end(), [&] (point lhs, point rhs) {
        if (lhs.x == rhs.x) {
            return lhs.y > rhs.y; // 若要求下凸壳,改成 <
        } else {
            return lhs.x < rhs.x;
        }
    });

    std::vector<point> hull;
    for (point p : seq) {
        if (hull.size() && hull.back().x == p.x) { // 注意考虑重复的点
            continue;
        }
        while (hull.size() >= 2 && check(hull.rbegin()[1], hull.back(), p)) {
            hull.pop_back();
        }
        hull.push_back(p);
    }
    return hull;
}
posted @ 2022-12-19 10:23  Calculatelove  阅读(277)  评论(0)    收藏  举报