- #include <iostream>#include <vector>#include <queue>#include <cmath>#include <climits>#include <unordered_set>#include <utility>#include <iomanip>using namespace std;struct Point { int x, y; Point(int x_, int y_) : x(x_), y(y_) {} bool operator==(const Point& other) const { return x == other.x && y == other.y; }};namespace std { template<> struct hash<Point> { size_t operator()(const Point& p) const { return p.x * 1000 + p.y; } };}double calculateDistance(int x1, int y1, int x2, int y2, bool isPark) { if (isPark) { return sqrt(pow((x2 - x1) * 100, 2) + pow((y2 - y1) * 100, 2)); } else { return abs(x2 - x1) * 100 + abs(y2 - y1) * 100; }}double shortestPath(int N, int M, const unordered_set<Point>& parks) { vector<vector<double>> dist(M + 1, vector<double>(N + 1, INT_MAX)); dist[1][1] = 0; priority_queue<pair<double, Point>, vector<pair<double, Point>>, greater<pair<double, Point>>> pq; pq.push({0, Point(1, 1)}); int dx4[] = {-1, 1, 0, 0}; int dy4[] = {0, 0, -1, 1}; int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}; int dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1}; while (!pq.empty()) { auto current = pq.top(); pq.pop(); double currentDist = current.first; Point u = current.second; if (u.x == M && u.y == N) { return currentDist; } if (currentDist > dist[u.x][u.y]) { continue; } bool isPark = parks.find(u) != parks.end(); if (isPark) { for (int i = 0; i < 8; ++i) { int nx = u.x + dx8[i]; int ny = u.y + dy8[i]; if (nx >= 1 && nx <= M && ny >= 1 && ny <= N) { double newDist = currentDist + calculateDistance(u.x, u.y, nx, ny, true); if (newDist < dist[nx][ny]) { dist[nx][ny] = newDist; pq.push({newDist, Point(nx, ny)}); } } } } else { for (int i = 0; i < 4; ++i) { int nx = u.x + dx4[i]; int ny = u.y + dy4[i]; if (nx >= 1 && nx <= M && ny >= 1 && ny <= N) { double newDist = currentDist + calculateDistance(u.x, u.y, nx, ny, false); if (newDist < dist[nx][ny]) { dist[nx][ny] = newDist; pq.push({newDist, Point(nx, ny)}); } } } } } return dist[M][N];}int main() { int N, M; cin >> N >> M; int K; cin >> K; unordered_set<Point> parks; for (int i = 0; i < K; ++i) { int x, y; cin >> x >> y; parks.insert(Point(x, y)); } double distance = shortestPath(N, M, parks); cout << static_cast<int>(round(distance)) << endl; return 0;}
复制代码 |