c++实现蛮力法凹包问题,给出输入规模为25的
时间: 2024-05-10 20:18:07 浏览: 101
实现凸包问题可以使用蛮力法(也称作朴素法),其时间复杂度是 $O(n^2)$,其中 $n$ 是输入点的个数。以下是一个 C++ 实现:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
int x, y;
};
// 求两点之间的距离
double dist(const Point& p1, const Point& p2) {
int dx = p1.x - p2.x;
int dy = p1.y - p2.y;
return sqrt(dx*dx + dy*dy);
}
// 判断三点是否共线
bool collinear(const Point& p1, const Point& p2, const Point& p3) {
return (p3.y - p2.y) * (p2.x - p1.x) == (p2.y - p1.y) * (p3.x - p2.x);
}
// 判断 p1-p2-p3 是否为逆时针方向
bool ccw(const Point& p1, const Point& p2, const Point& p3) {
return (p2.x - p1.x) * (p3.y - p2.y) > (p2.y - p1.y) * (p3.x - p2.x);
}
// 求凸包,返回凸包上的点集
vector<Point> convexHull(const vector<Point>& points) {
int n = points.size();
if (n <= 2) {
return points;
}
vector<Point> hull;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
bool valid = true;
for (int k = 0; k < n; k++) {
if (k == i || k == j) {
continue;
}
if (ccw(points[i], points[j], points[k])) {
valid = false;
break;
}
if (collinear(points[i], points[j], points[k]) && dist(points[i], points[j]) < dist(points[i], points[k])) {
valid = false;
break;
}
}
if (valid) {
hull.push_back(points[i]);
hull.push_back(points[j]);
}
}
}
sort(hull.begin(), hull.end(), [](const Point& p1, const Point& p2) {
return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
});
vector<Point> ans;
ans.push_back(hull[0]);
ans.push_back(hull[1]);
for (int i = 2; i < hull.size(); i++) {
while (ans.size() >= 2 && !ccw(ans[ans.size()-2], ans[ans.size()-1], hull[i])) {
ans.pop_back();
}
ans.push_back(hull[i]);
}
return ans;
}
int main() {
// 构造输入数据
vector<Point> points = {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0},
{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1},
{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}};
vector<Point> hull = convexHull(points);
for (const auto& p : hull) {
cout << "(" << p.x << ", " << p.y << ") ";
}
cout << endl;
return 0;
}
```
以上代码中,我们首先定义了 `Point` 结构体表示一个点,然后实现了 `dist` 函数计算两点之间的距离,`collinear` 函数判断三点是否共线,`ccw` 函数判断三点是否为逆时针方向。最后,我们实现了 `convexHull` 函数求解凸包,该函数使用两层循环枚举所有可能的边,对于每条边,遍历所有点判断它们是否在这条边的左侧,如果都在左侧,则这条边是凸包的一部分。最后,我们对所有边按照极角排序,然后使用单调栈求解凸包。
对于输入规模为 $25$ 的测试数据,可以将上述代码中的 `points` 数组替换为对应的输入数据即可。
阅读全文