1.题目描述:
输入样例:
3 3
S*#
**#
#*E
输出样例:
4
问题解决(下面的代码可看做模板):
套模板时要注意改动的地方:
(1)寻找路径的时候,一个点被践踏多次,所以回溯的时候要把这个点标记为0(没走过)
(2)根据题目,有上、下、左、右四个方向
主函数
int main{
ans=99999999是为了第一次min的时候,让ans=step
注意:
(1)mpt和vis都需要初始化成0,mpt初始化为0的目的是,待会赋值完后图以外的地方都为0,就形成了一个边界
(2)输入图时的for循环,i从1开始的,scanf的时候从mpt[i]+1开始的,也就是说不去用图的第0行和第0列。这样的好处是,在dfs函数中,不需要判断dx,dy减1后是否超出边界(变成-1)。
#include<bits/stdc++.h>
using namespace std;
char grid[101][101];
int vis[101][101];
//大括号内含小括号!!!
int dir[4][2] = { {-1, 0}, {0, -1}, {0, 1}, {1, 0}};
int ans=9999999;
void DFS(int x, int y,int step)
{
if(step>ans) //剪枝 (可以不考虑)
return;
if(grid[x][y]=='E'){
ans=min(ans,step);
return;//递归出口--终点
}
for(int i = 0; i<4; i++)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
//if(xx<0 || xx>=n || yy<0 || yy>=m) continue; //越界终止本次循环
if((grid[xx][yy] == '*'||grid[xx][yy]=='E')&&vis[xx][yy]==0) {
vis[xx][yy]=1; //关键代码 !!
DFS(xx, yy,step+1); //关键代码!!
vis[xx][yy]=0; //关键代码!!回溯!!!
}
}
}
int main()
{
int h,w;
int i, j;
while(scanf("%d%d", &h, &w))
{
if(h == 0 && w == 0) break;
memset(grid, 0, sizeof(grid));
memset(vis, 0, sizeof(vis));
for(i = 1; i <=h; i++) //避免从第0行开始
scanf("%s", grid[i]+1); //避免从第0列开始
for(i = 1; i <=h; i++){ //从第1行开始搜索
for(j = 1; j <=w; j++){ //从第1行开始搜索
if(grid[i][j] == 'S')
{
vis[i][j]=1; //关键代码!!
DFS(i, j,0); //关键代码!!
}
}
}
printf("%d\n",ans);
}
return 0;
}