题解何意味
2025-09-04 22:05:55
发布于:湖北
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> Point; // 定义点的类型,使用long long存储坐标
// 计算向量OA和OB的叉积,用于判断点的相对位置
ll cross(const Point &O, const Point &A, const Point &B) {
return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);
}
// 计算两点之间距离的平方,避免开方运算,提高效率
ll distSq(const Point &A, const Point &B) {
ll dx = A.first - B.first;
ll dy = A.second - B.second;
return dxdx + dydy;
}
// Andrew的单调链算法构建凸包
vector<Point> convexHull(vector<Point> &points) {
int n = points.size();
if (n <= 1) return points; // 如果点集少于等于1个点,直接返回
sort(points.begin(), points.end()); // 按照x坐标排序,若x相同则按y排序
vector<Point> hull; // 存储凸包的点
hull.reserve(n + 1); // 预分配空间,提高效率
// 构建下凸包
for (int i = 0; i < n; ++i) {
// 当栈内至少有两个点,且新点会导致非凸时,弹出栈顶点
while (hull.size() >= 2 && cross(hull[hull.size()-2], hull.back(), points[i]) <= 0)
hull.pop_back();
hull.push_back(points[i]); // 将当前点加入凸包
}
// 构建上凸包
int lower_hull_size = hull.size(); // 记录下凸包的大小
for (int i = n-2; i >= 0; --i) {
// 类似下凸包的构建,但方向相反
while (hull.size() > lower_hull_size && cross(hull[hull.size()-2], hull.back(), points[i]) <= 0)
hull.pop_back();
hull.push_back(points[i]);
}
// 移除最后一个点(与第一个点重复)
if (hull.size() > 1) hull.pop_back();
return hull;
}
// 旋转卡壳算法找到凸包的最大直径平方
ll rotatingCalipers(vector<Point> &hull) {
int n = hull.size();
if (n == 1) return 0; // 如果凸包只有一个点,直径为0
if (n == 2) return distSq(hull[0], hull[1]); // 如果凸包只有两个点,直接计算距离平方
ll maxDistSq = 0; // 初始化最大距离平方
int j = 1; // 初始化第二个点的索引
for (int i = 0; i < n; ++i) {
Point a = hull[i]; // 当前点
Point b = hull[(i + 1) % n]; // 下一个点,循环处理
// 移动j,直到三角形(i, i+1, j+1)的面积大于三角形(i, i+1, j)的面积
while (cross(a, b, hull[(j + 1) % n]) > cross(a, b, hull[j])) {
j = (j + 1) % n;
}
// 更新最大距离平方
maxDistSq = max(maxDistSq, distSq(hull[i], hull[j]));
}
return maxDistSq;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n; // 输入点的数量
vector<Point> points(n);
for (int i = 0; i < n; ++i) {
cin >> points[i].first >> points[i].second; // 输入每个点的坐标
}
vector<Point> hull = convexHull(points); // 构建凸包
cout << rotatingCalipers(hull) << endl; // 计算并输出凸包直径的平方
return 0;
}
这里空空如也
有帮助,赞一个