迷宫搜
每次搜索都要判断是否到达终点,如果到达就结束
否则要判断是否可以移动到与当前位置相邻的上、下、左、右四个点
如果可以移动,就进行移动,递归地进行下一步搜索。
每个位置的合法性要考虑以下方面:
- 必须在给定的迷宫范围内。
- 必须是没有被访问过(是否访问过可以用数组标记)。
- 必须不是墙壁。
bool check(int x,int y){
if((x>=0&&y>=0&&x<n&&y<m)&&(!vis[x][y])&&(maze[x][y]!='*')){
return true;
}
return false;
}
DFS迷宫搜是否可以到终点模板代码:
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; //dx与dy记录x和y的变化
bool dfs(int x,int y){ //参数描述状态
if(maze[x][y]=='T')return true; //如果到达终点
vis[x][y]=true; //当前点搜过了
for(int i=0;i<4;i++){ //枚举相邻四个点
int tx=x+dx[i],ty=y+dy[i]; //tx,ty:移动后的坐标
if(check(tx,ty)){ //若下一步合法
if(dfs(tx,ty))return true; //以下一步为当前点开始搜索
}
}
return false; //到不了终点
}
迷宫搜——方案数问题
需要回溯(试探标记,进行递归,取消标记),要将所有方案找到。
DFS迷宫搜到终点的方案数模板代码:
int ans = 0; // 全局变量自动清 0 ,所以不手动初始化也行
int dir[4][2] = { { -1, 0},{0, -1},{1, 0},{0, 1}};
void dfs(int x, int y) {
if (maze[x][y] == 'T') {
ans++;
return;
}
vis[x][y] = true;
for (int i = 0; i < 4; i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
dfs(tx, ty);
}
}
vis[x][y] = false;
}
迷宫搜——最短路路问题
需要回溯(试探标记,进行递归,取消标记),要将所有方案找到,在比较步数。
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int ans=INT_MAX;
void dfs(int x, int y) {
if (maze[x][y] == 'T') {
ans=min(ans,step);
return;
}
vis[x][y] = true;
for (int i = 0; i < 4; i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if (check(tx,ty) {
dfs(tx, ty,step+1);
}
}
vis[x][y] = false;
}