1 条题解
-
0
题意分析
Mothy 需要在牛仔裤的表面上找到一条最短路径,从他所在的位置到他母亲的位置。牛仔裤上有多个补丁(凸多边形),Mothy 不能穿过补丁的内部,但可以在补丁的边缘移动。
解题思路
-
图的构建:
- 将 Mothy 的位置、他母亲的位置以及所有补丁的顶点视为图的节点。
- 如果两个节点之间可以直接通过牛仔裤表面移动(不穿过任何补丁),则在它们之间添加一条边,权重为两点之间的欧几里得距离。
-
最短路径算法:
- 使用 Dijkstra 算法或 A* 算法计算从 Mothy 的位置到他母亲的位置的最短路径。
-
障碍物检测:
- 在构建图时,需要检测路径是否穿过任何补丁的内部。如果是,则不能添加这条边。
-
输出结果:
- 如果找到最短路径,则输出其长度,保留三位小数。
- 如果无法找到路径,则输出 。
C++ 代码实现
#include <iostream> #include <vector> #include <cmath> #include <queue> #include <iomanip> using namespace std; struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} }; // 计算两点之间的欧几里得距离 double distance(const Point& p1, const Point& p2) { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); } // 检查线段是否与多边形相交 bool isSegmentIntersectPolygon(const Point& p1, const Point& p2, const vector<Point>& polygon) { // 实现线段与多边形的相交检测 // 这里省略具体实现 return false; } int main() { int T; cin >> T; while (T--) { int N; Point start, end; cin >> N >> start.x >> start.y >> end.x >> end.y; vector<vector<Point>> patches(N); for (int i = 0; i < N; ++i) { int vertices; cin >> vertices; patches[i].resize(vertices); for (int j = 0; j < vertices; ++j) { cin >> patches[i][j].x >> patches[i][j].y; } } // 构建图的节点 vector<Point> nodes = {start, end}; for (const auto& patch : patches) { for (const auto& vertex : patch) { nodes.push_back(vertex); } } // 构建图的边 vector<vector<pair<int, double>>> graph(nodes.size()); for (int i = 0; i < nodes.size(); ++i) { for (int j = i + 1; j < nodes.size(); ++j) { bool canConnect = true; for (const auto& patch : patches) { if (isSegmentIntersectPolygon(nodes[i], nodes[j], patch)) { canConnect = false; break; } } if (canConnect) { double dist = distance(nodes[i], nodes[j]); graph[i].emplace_back(j, dist); graph[j].emplace_back(i, dist); } } } // Dijkstra 算法计算最短路径 vector<double> dist(nodes.size(), 1e9); dist[0] = 0; priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq; pq.emplace(0, 0); while (!pq.empty()) { double d = pq.top().first; int u = pq.top().second; pq.pop(); if (d > dist[u]) continue; for (const auto& edge : graph[u]) { int v = edge.first; double w = edge.second; if (dist[v] > dist[u] + w) { dist[v] = dist[u] + w; pq.emplace(dist[v], v); } } } // 输出结果 if (dist[1] < 1e9) { cout << fixed << setprecision(3) << dist[1] << endl; } else { cout << -1 << endl; } } return 0; }
代码解释
-
Point
结构体:- 表示平面中的一个点。
-
distance
函数:- 计算两点之间的欧几里得距离。
-
isSegmentIntersectPolygon
函数:- 检查线段是否与多边形相交(具体实现省略)。
-
图的构建:
- 将 Mothy 的位置、他母亲的位置以及所有补丁的顶点作为图的节点。
- 如果两个节点之间的路径不穿过任何补丁,则在它们之间添加一条边。
-
Dijkstra 算法:
- 计算从 Mothy 的位置到他母亲的位置的最短路径。
-
输出结果:
- 如果找到最短路径,则输出其长度,保留三位小数。
- 如果无法找到路径,则输出 。
复杂度分析
-
时间复杂度:
- 构建图的时间复杂度为 ,其中 是补丁数量, 是顶点总数。
- Dijkstra 算法的时间复杂度为 。
-
空间复杂度:
- 需要 的空间存储图。
总结
通过构建图和使用 Dijkstra 算法,我们可以高效地计算 Mothy 的最短路径,确保他能够以最快的方式找到他的母亲。
-
- 1
信息
- ID
- 1678
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者