*来源 * 啊哈算法!
有一天,小哈一个人去玩迷宫。但是方向感不好的小哈很快就迷路了。小哼得知后便去解救无助的小哈。此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈。那么,问题来了…
输入
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
输出
7
我们先来分析一下可能的道路
如图
此图表现的思想就是DFS(深度优先搜索)
也就是按既定的顺序进行搜寻
如(右下左上)
从起点往右走 直到走不通就尝试往下走
如果上下左右都走不通
就回溯到上一个状态(继续尝试当前状态的其他方向)
然后上代码 体会一下
#include<stdio.h>
int n, m, p, q, min = 99999999;
int a[51][51], book[51][51];//book用来标志是否走过
void dfs(int x, int y, int step)
{
int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };//四个方向,注意行列
int tx, ty, k;
if (x == p && y == q)
{
if (step < min)//更新最少步数
min = step;
return;
}
for (k = 0; k <= 3; k++)
{
tx = x + next[k][0];//更新位置
ty = y + next[k][1];
if (tx<1 || tx>n || ty<1 || ty>m)//判断下一步是否在界面内
continue;
if (a[tx][ty] == 0 && book[tx][ty] == 0)//没有障碍且没有走过就走
{
book[tx][ty] = 1;
dfs(tx, ty, step + 1);//递归实现遍历所有情况
book[tx][ty] = 0;
}
}
return;//这个return 很重要 不然就死循环了
}
int main()
{
int i, j, startx, starty;//当前位置 出口位置
scanf("%d %d", &n, &m);
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
scanf("%d %d %d %d", &startx, &starty, &p, &q);
book[startx][starty] = 1;
dfs(startx, starty, 0);
printf("%d", min);
getchar();//暂停一下 怕闪退
return 0;
}
再谈BFS(广度优先搜索)
也就字面意思
广度(脑补一下丢块石子在池中,波纹一圈一圈荡开)
BFS也就是类似的意思
一层一层的去搜索并标记;
因此BFS找到的第一个可行解必是最优解 程序就可退出
emmmm我没找到图 自己脑补吧
要用队列来实现
就是说从当前点开始
向外扩展一圈(当然不能是障碍物)
并且把外面一圈标记+1;
再将外面一圈依次标记更外面一圈 再标记加一
知道终点被标记 那么标记的值就是最短步数!!
#include <iostream>
#include <cstdio>>
#include <algorithm>
#include <queue>
#define INF 99999999
using namespace std;
typedef struct Node {
int x, y;//当前坐标
int step;//步数
}node;
const int maxn = 105;
int minx = INF;
int n, m;
int sx, sy, hx, hy;
int a[105][105];
int vis[maxn][maxn];
int dir[4][2] = { 0,1,-1,0,0,-1,1,0 };//四个方向
void bfs(int x, int y) {
node p, q;
p.x = x;
p.y = y;
p.step = 0;
queue<node> pq;
pq.push(p);
while (!pq.empty()) {
p = pq.front();
pq.pop();
if (p.x == hx && p.y == hy) {
minx = p.step;
return;
}
}
for (int i = 0; i < 4; i++) {
q.x = p.x + dir[i][0];
q.y = p.y + dir[i][1];
q.step = p.step + 1;
if (q.x<1 || q.x>n || q.y<1 || q.y>m)//判断是否越界
continue;
if (!vis[q.x][q.y] && a[q.x][q.y] != 1) {//如果这个点没有走过或者这个点不是障碍物,则可以走
vis[q.x][q.y] = 1;
pq.push(q);
}
}
return;
}
int main()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
scanf("%d %d %d %d", &sx, &sy, &hx, &hy);
vis[sx][sy] = 1;
bfs(sx, sy);
if (minx == INF) printf("No Way!\n");
else printf("%d\n", minx);
return 0;
}