计蒜客《迷宫询问》题解

题目传送门:Jisuanke

大家好!这是本蒟蒻第一次写代码(第二次发博客😁!),请大家多多支持,有更好的方法请各位大神多多指正。

题目描述

给定一个n×m的迷宫,迷宫中有一个固定位置的出口T,入口位置未定,同时迷宫中有些地方是空地,可以穿越,有些地方是 障碍,必须绕行,每次从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,不能走到迷宫外面去。
现在蒜头君有Q次询问,每次询问会告诉你一个入口S的位置,你需要计算出每个S走到T的最短距离。 输入格式
第一行三个正整数n,m,Q,表示迷宫的大小和询问的次数。
接下来n行,每行m个字符,其中字符表示该位置为空地,字符*表示该位置为障碍,字符'T表示该位置为迷宫的 出口,输入数据中只有这三种字符。
接下来Q行,每行两个正整数(x,yi),表示第i次询问起点S在(xi,yi)处,数据保证(xi,yi)总是为空地。 输出格式
输出共Q行,每行一个整数,第i行的输出表示第i次询问中S到T的最短距离,如果不能到达,则输出—1。

数据范围


对于20%的数据,1≤n,m≤20,q=1。
对于另外20%的数据,1<n,m≤20,1≤q≤10。 对于另外20%的数据,1≤n,m<1000,q=1。
对于另外20%的数据,1≤n,m≤1000,1≤q≤10。 对于100%的数据,1≤n,m≤1000,1≤q≤105。 

测试样例

输入:
6 5 3
.*.*.
.*...
..**.
.....
.*..*
....T
1 1
2 3
4 5
输出:
9
8
4

 

话不多说,上代码~

80%代码:

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n, m, Q, a, b;
string maze[1005];
bool vis[1005][1005] = {0};
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
bool in(int x, int y) {
    return 0 <= x && x < n && 0 <= y && y < m;
}
struct node {
    int x, y, d;
    node(int _x, int _y, int _d) {
        x = _x;
        y = _y;
        d = _d;
    }
};
int bfs(int sx, int sy) {
    queue<node> q;
    vis[sx][sy] = true;
    q.push(node(sx, sy, 0));
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        if (now.x == a - 1 && now.y == b - 1) {
            return now.d;
        }
        for (int i = 0; i < 4; i++) {
            int tx = now.x - dir[i][0];
            int ty = now.y - dir[i][1];
            if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
                vis[tx][ty] = true;
                q.push(node(tx, ty, now.d + 1));
            }
        }
    }
    return -1;
}
int main() {
    freopen("query.in", "r", stdin);
    freopen("query.out", "w", stdout);
    cin >> n >> m >> Q;
    for (int i = 0; i < n; i++) {
        cin >> maze[i];
    }
    int x, y;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (maze[i][j] == 'T') {
                x = i;
                y = j;
            }
        }
    }
    for (int i = 1; i <= Q; i++) {
        cin >> a >> b;
        for (int j = 0; j < 1005; j++) {
            for (int k = 0; k < 1005; k++) {
                vis[j][k] = false;
            }
        } 
        cout << bfs(x, y) << endl;
    }
    return 0;
}

代码分析:

此代码虽然可以求出迷宫最优解,但遇到大数据时,此算法的效率太低了,会造成超时错误。

AC代码:

 #include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n, m, Q;
char maze[1005][1005];
bool vis[1005][1005] = {0};
int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
int dis[1005][1005];
struct node {
    int x, y, step;
};
queue <node> q;
bool in (int x, int y) {
    return x >= 1 && x <= n && y >= 1 && y <= m;
}
void bfs (int sx, int sy) {
    memset(dis, -1, sizeof(dis));
    vis[sx][sy] = 0;
    q.push(node{sx, sy, 0});
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int tx = now.x + dir[i][0];
            int ty = now.y + dir[i][1];
            if (in(tx, ty) && maze[tx][ty] == '.' && dis[tx][ty] == -1) {
                dis[tx][ty] = now.step + 1;
                q.push(node{tx, ty, now.step + 1});
            }
        }
    }
}
int main () {
    freopen("query.in", "r", stdin);
    freopen("query.out", "w", stdout);
    cin >> n >> m >> Q;
    int x, y;
    for (int i = 1; i <= n; i++) {
        cin >> maze[i] + 1;
        for (int j = 1; j <= m; j++) {
            if (maze[i][j] == 'T') {
                x = i, y = j;
            }
        }
    }
    bfs(x, y);
    while (Q--) {
        cin >> x >> y;
        cout << dis[x][y] << endl;
    }
    return 0;
}

本期文章就到这里,如果有什么问题,请大家多多指正。

最后,恳请大家点赞、关注、转发!😀

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值