AcWing 走迷宫问题
给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。
数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。
输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含 m 个整数(0 或 1),表示完整的二维数组迷宫。
输出格式
输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围
1≤n,m≤100
输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
8
解答:
这是一个简单的dfs问题,从起点开始,往前走第一步,记录下所有第一步能走到的点,然后从所第一步能走到的点开始,往前走第二步,记录下所有第二步能走到的点,重复下去,直到走到终点。输出步数即可,上代码!
代码(ans)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int map[110][110];//图
int n, m;
int dx[4] = { 0,1,-1,0 };//方向数组
int dy[4] = { 1,0,0,-1 };
bool check[110][110];//判断是否走过
struct point {
int x;
int y;
int num;
};//建立结构体,存储坐标及其步数
queue<point> r;//建立队列
int bfs()
{
point start;
start.x = 0;
start.y = 0;
start.num = 0;
r.push(start);//入队
check[0][0] = 1;//标记,表示搜索过
while (!r.empty())
{
int x = r.front().x, y = r.front().y;
if (x == n - 1 && y == m - 1)//到达目标点
{
return r.front().num;
}
for (int i = 0; i < 4; i++)
{
int tx, ty;
tx = r.front().x + dx[i];
ty = r.front().y + dy[i];
if (map[tx][ty] == 1 && check[tx][ty] == 0)
{
point step;
step.x = tx;
step.y = ty;
step.num = r.front().num + 1;
r.push(step);//入队
check[tx][ty] = 1;//标记
}
}
r.pop();//出队
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i <n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> map[i][j];//习惯将障碍物定做0,可以走的当做1,以后边界比较好找(不需要判断边界,0就是边界了)
if (map[i][j] == 0)
{
map[i][j] = 1;
continue;
}
if (map[i][j] == 1)
{
map[i][j] = 0;
continue;
}
}
}
cout << bfs() << endl;
return 0;
}