题目描述

有一天,小哈一个去玩迷宫。但是方向感很不好的小哈很快就迷路了。小哼得知后便立即去解救无助的小哈。小哼当然是有备而来,已经弄清楚了迷宫地图,现在小哼要以最快速度去解救小哈。问题就此开始了…… 迷宫由$n \times m$列的单元格组成,每个单元格要么是空地,要么是障碍物。你的任务是帮助小哼找到一条从迷宫的起点到小哈所在位置的最短路径,注意障碍物是不能走的,当然也不能走到迷宫之外。$n$,$m \le 100$。

输入

第一行有两个数$n$和$m$。$n$表示迷宫的行,$m$表示迷宫的列。接来下来$n$行$m$列为迷宫,0表示空地,1表示障碍物。最后一行4个数,前两个数为迷宫入口的$x$和$y$坐标。后两个为小哈的$x$和$y$坐标。

输出

一个整数表示小哼到小哈的最短步数。如果不能解救小哈则输出$No Way$!

样例输入

5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
3 3
1 1 1 
0 1 0 
0 1 0 
2 1 3 3

样例输出

7
No Way!

题解

#include<iostream>
#include <queue>
#include <cstring>

using namespace std;
using ll = long long;
#define endl '\n'

template<typename T=int>
inline T read() {
    T x;
    cin >> x;
    return x;
}

const int maxn = 110;
bool book[maxn][maxn];
int G[maxn][maxn];
int M, N;
int fx[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
struct Node {
    int x, y, z;
    Node *pre;
};

void bfs(int sx, int sy, int ex, int ey) {//O(m*n)
    int ans = 0;
    queue<Node> Q;
    Q.push({sx, sy, 0});
    book[sx][sy] = true;
    while (Q.size()) {
        auto &pt = Q.front();
        int x = pt.x;
        int y = pt.y;
        int z = pt.z;
        if (x == ex && y == ey) {
            cout << z << endl;
            return;
        }
        Q.pop();
        for (auto &i: fx) {
            int nx = x + i[0];
            int ny = y + i[1];
            if (nx < 1 || nx > M || ny < 1 || ny > N || book[nx][ny] || G[nx][ny] == 1)continue;
            book[nx][ny] = true;
            Q.push({nx, ny, z + 1});
            book[nx][ny] = 1;
        }
    }
    cout << "No Way!" << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int ex, ey, sx, sy;
    while (cin >> M >> N) {
        memset(book, 0, sizeof(book));
        for (int i = 1; i <= M; i++)
            for (int j = 1; j <= N; j++) {
                cin >> G[i][j];
            }
        cin >> sx >> sy >> ex >> ey;

        bfs(sx, sy, ex, ey);
    }
    return 0;
}