·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

那位大佬会c++。帮我做道题!

59 3
发表于 前天 20:25 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
抄近路描述琳琳每天要从家到车站,小区被道路分成许多正方形的块,共有N×M块,一般情况下,小区内的方块建有房屋,只能沿着附近的街道行走,有时方块表示公园,那么就可以直接穿过。
请你帮她计算一下从家到车站的最短距离。
输入第一行是N和M。注意,琳琳家坐标在方块(1,1)的西南角,车站在方块(M,N)的东北角。每个方块边长100米。接下来一行是整数K,表示可以对角线穿过的方块数,然后有K行,每行两个数,表示一个坐标。
输出输出最短距离,四舍五入到整数米。
样例输入3 231 13 21 2输出383提示0<N,M≤1000
我要说一句 收起回复

评论3

婷姐Lv.8 发表于 前天 20:26 | 查看全部
  1. #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;}
复制代码
我要说一句 收起回复
拾光Lv.8 发表于 前天 20:26 | 查看全部
优先队列(堆优化)
  1. priority_queue<pair<int, Point>, vector<pair<int, Point>>, greater<pair<int, Point>>> pq;pq.push({0, start});while (!pq.empty()) {    auto [dist, u] = pq.top(); pq.pop();    if (dist > distance[u.x][u.y]) continue; // 跳过已处理的节点    for (auto [v, w] : neighbors) {        if (distance[v.x][v.y] > dist + w) {            distance[v.x][v.y] = dist + w;            pq.push({distance[v.x][v.y], v});        }    }}
复制代码
邻接表代替邻接矩阵
  1. vector<vector<pair<Point, int>>> adj(N * M); // 邻接表for (int i = 0; i < N; i++) {    for (int j = 0; j < M; j++) {        for (auto [dx, dy] : directions) {            int nx = i + dx, ny = j + dy;            if (nx >= 0 && nx < N && ny >= 0 && ny < M) {                adj[i * M + j].emplace_back(Point(nx, ny), weight);            }        }    }}
复制代码
双向Dijkstra或A*算法
  1. // 双向Dijkstraunordered_set<Point> visited_start, visited_end;queue<Point> q_start, q_end;q_start.push(start); q_end.push(end);while (!q_start.empty() && !q_end.empty()) {    expand(q_start, visited_start, visited_end); // 检查是否相遇    expand(q_end, visited_end, visited_start);}
复制代码
我要说一句 收起回复
CrystαlLv.8 发表于 前天 20:27 | 查看全部
没通过测试啊
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文热点
关闭

站长推荐上一条 /1 下一条

最新热评 加载中...
AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:216.73.216.74,GMT+8, 2025-5-29 06:41 , Processed in 0.277538 second(s), 90 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表