一道经典迷宫题目:使用bfs与dfs都可以解,dfs时间复杂度高一点
非常非常好的题
Description>
第一行输入两个整数n和 m,表示这是一个 n×m 的迷宫。接下来的输入一个 n 行 m 列的迷宫。其中 ‘S’ 表示蒜头君的位置,’*‘表示墙,蒜头君无法通过,’.‘表示路,蒜头君可以通过’.'移动,'T’表示迷宫的出口(蒜头君每次只能移动到四个与他相邻的位置——上,下,左,右)。
输出蒜头君逃出迷宫的最少步数,如果蒜头君无法逃出迷宫输出 −1。
Inpot>
3 4
S**.
…*.
***T
Outpot>
-1
Inpot>
3 4
S**.
…*.
***T
Outpot>
5
首先是DFS的方法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int p,q; //迷宫出口
int m,n; //迷宫大小
char mmap[110][110];//迷宫
bool vis[110][110]; //标记
int mmin;
int a[4]={1,-1,0,0};
int b[4]={0,0,-1,1};
void dfs(int x,int y,int step)
{
if(x==p && y==q){
if(mmin>step){
mmin = step;
}
return ;
}
for(int i=0;i<4;i++){
int tx,ty;
tx = x + a[i];
ty = y + b[i];
if(tx>=0&&ty>=0&&tx<n&&ty<m && vis[tx][ty]==0){
if(mmap[tx][ty]=='.' || mmap[tx][ty]=='T'){
vis[tx][ty] = 1;
dfs(tx,ty,step+1);
vis[tx][ty] = 0;
}
}
}
}
int main()
{
//memset(vis,0,sizeof(vis));
//memset(mmap,'\0',sizeof(mmap));
mmin=99999999;
int i,j;
int sx,sy; //迷宫入口
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
cin>>mmap[i][j]; //只能用%s和cin>>
if(mmap[i][j] == 'T'){p = i; q = j;}//出口
if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
}
}
vis[sx][sy] = 1;//标记入口走过
dfs(sx,sy,0); //步数0
if(mmin==99999999) printf("-1\n");
else printf("%d\n",mmin);
return 0;
}
BFS的方法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
int m,n; //迷宫大小
char mmap[110][110];//迷宫
bool vis[110][110]; //标记
int a[4]={1,-1,0,0};//四个方向
int b[4]={0,0,-1,1};//四个方向
struct node{
int x,y,step;
};
bool check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&mmap[x][y]!='*'&&vis[x][y]==0)
return 1;
return 0;
}
int bfs(int x,int y)
{
queue<node>q;
node p;
p.x = x;
p.y = y;
p.step = 0;
q.push(p);
while(!q.empty()){
p = q.front();
q.pop();
if(mmap[p.x][p.y]=='T')//到达出口跳出
return p.step;
for(int i = 0;i<4;i++){
int xx = p.x + a[i];
int yy = p.y + b[i];
if( check(xx,yy) ){
vis[xx][yy] = 1;
node e;
e.x = xx;
e.y = yy;
e.step = p.step+1;
q.push(e);
}
}
}
return -1;
}
int main()
{
int i,j;
int sx,sy; //迷宫入口
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
cin>>mmap[i][j]; //只能用%s和cin>>
if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
}
}
vis[sx][sy] = 1;//标记入口走过
printf("%d\n",bfs(sx,sy));
return 0;
}
迷宫的升级版本还有路径输出以及利用优先+BFS解决加权问题
下面把上面改成了求路径问题,题目一样,只输出了路径。
利用BFS和队列
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
int m,n; //迷宫大小
char mmap[100][100];//迷宫
bool vis[100][100]; //标记
int a[4]={1,-1,0,0};//四个方向
int b[4]={0,0,-1,1};//四个方向
int tx,ty; //迷宫出口
int sx,sy; //迷宫入口
struct node{
int x,y;
};
node pre[100][100];
bool check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&mmap[x][y]!='*'&&vis[x][y]==0)
return 1;
return 0;
}
void bfs(int x,int y)
{
queue<node>q;
node p;
p.x = x;
p.y = y;
q.push(p);
while(!q.empty()){
p = q.front();
q.pop();
if(mmap[p.x][p.y]=='T')//到达出口跳出
return ;
for(int i = 0;i<4;i++){
node e;
e.x = p.x + a[i];
e.y = p.y + b[i];
if( check(e.x,e.y) ){
vis[e.x][e.y] = 1;
q.push(e);
pre[e.x][e.y] = p;
}
}
}
}
void prin(node k){ //逆向输出
if(sx==k.x&&sy==k.y) {
printf("(0,0)\n");
return ;
}
prin(pre[k.x][k.y]);
printf("(%d,%d)\n",k.x,k.y);
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
cin>>mmap[i][j]; //只能用%s和cin>>
if(mmap[i][j] == 'T'){tx= i; ty= j;}//出口
if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
}
}
vis[sx][sy] = 1;//标记入口走过
bfs(sx,sy);
node k;
k.x = tx,k.y = ty;
prin(k);
return 0;
}