第二周_自学算法
1. DFS 和 BFS
迷宫问题:
题意:
找到从起点到终点的最短路径长度。
思路1:
深度优先搜索 (DFS)
从起始位置出发, 按照顺时针方向沿着一个方向向下试探, 找到终点, 若还有其他可到达终点的路径就回溯, 以此类推找到所有可到达终点的路径, 过程中记录能到达终点的较短路径, 最后输出最短路径。
注: 每个位置都有上, 下, 左, 右四个方向可以走, 我们规定按顺时针方向右, 下, 左, 上进行探索
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 50; // 迷宫行和列的最大值
int n, m; // n 行, m列
int start_x, start_y, end_x, end_y; // 起始位置和终点坐标
int arr[N + 10][N + 10]; // 要输入的迷宫图, 用 1 表示是空地, 用 2 表示障碍物
int v[N + 10][N + 10]; // 标记, 1 表示已标记不能走, 0 表示是空地可以走
int min1 = INT_MAX; // 最短路径
int d_x[4] = {0, 1, 0, -1},
d_y[4] = {1, 0, -1, 0}; // 按右, 下, 左, 上探索
void dfs(int x, int y, int step) // 每走一个单元格 step 加 1
{
// 找到终点的情况
if (x == end_x && y == end_y)
{
if (step < min1) min1 = step;
return; // 回溯
}
// 探索
for (int k = 0; k < 4; k++)
{
int sx = x + d_x[k];
int sy = y + d_y[k];
// 判断能不能走
if (arr[sx][sy] == 1 && v[sx][sy] == 0)
{
v[sx][sy] = 1; // 能走就标记
dfs(sx, sy, step + 1); // 往前探索
v[sx][sy] = 0; // 回溯时收回标记
}
}
return;
}
int main(void)
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &arr[i][j]);
cin >> start_x >> start_y;
cin >> end_x >> end_y;
dfs(start_x, start_y, 0);
cout << min1;
return 0;
}
思路2:
广度优先搜索 (BFS)
将起点入队
若队首结点能扩展, 则将能扩展的点入队; 若队首不能再扩展, 则将队首结点出队
重复第二步, 直到到达终点或队为空时结束
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n, m; // n 行, m列
int start_x, start_y, end_x, end_y; // 起始位置和终点坐标
int arr[N + 10][N + 10]; // 要输入的迷宫图, 用 1 表示是空地, 用 2 表示障碍物
int v[N + 10][N + 10]; // 标记, 1 表示已标记不能走, 0 表示是空地可以走
int d_x[4] = {0, 1, 0, -1},
d_y[4] = {1, 0, -1, 0}; // 按右, 下, 左, 上探索
// 结点结构体
struct point
{
int x;
int y;
int step;
};
queue<point> p; // 申请队列
void bfs(int start_x, int start_y)
{
// 起点入队
point start;
start.x = start_x;
start.y = start_y;
start.step = 0;
p.push(start);
v[start_x][start_y] = 1;
while (!p.empty())
{
int x = p.front().x;
int y = p.front().y;
// 到达终点情况
if (x == end_x && y == end_y)
{
cout << p.front().step;
break;
}
// 探索
for (int k = 0; k < 4; k++)
{
int sx = x + d_x[k];
int sy = y + d_y[k];
if (arr[sx][sy] == 1 && v[sx][sy] == 0)
{
point temp;
temp.x = sx;
temp.y = sy;
temp.step = p.front().step + 1;
p.push(temp);
v[sx][sy] = 1;
}
}
p.pop(); // 不能或扩展完后就出队
}
}
int main(void)
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &arr[i][j]);
cin >> start_x >> start_y;
cin >> end_x >> end_y;
bfs(start_x, start_y);
return 0;
}
输入:
5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 1
1 1
4 3
输出:
7
标签:10,终点,end,int,step,start,算法,自学
From: https://www.cnblogs.com/Ailicode/p/17038844.html