比较简单的搜索题,用到了dfs和bfs。dfs比较适合搜索有无可行解,如本题中左转优先和右转优先是利用dfs算法求解得,而bfs适合寻找最优解,如本题最短路径就是bfs。
这道题有一个比较需要注意的地方就是bfs时用visit[][]记录是否访问时,一定要在加入que队列的时候就修改visit[x][y]的值,我第一次是在出队列的时候修改其值,因为想的是出队列时才是访问它的时候,但是这样就大错特错了!!RE了好久,真是伤不起。。。一定要在加入que时就修改visit!!
下面贴代码。
#include<iostream>
using namespace std;
char maze[41][41];
int nextmove[4][2]={0,1,1,0,0,-1,-1,0}; //方向分别是东、南、西、北
int lcount,rcount;
char visit[41][41];
void left(int x,int y,int dir,int w,int h){
lcount++;
if (maze[x][y]=='E') return;
int ndir,nx,ny;
for (int i=3;i<=6;i++){ //左转和右转先后次序是不一样的!
ndir=(dir+i)%4;
nx=x+nextmove[(dir+i)%4][0];
ny=y+nextmove[(dir+i)%4][1];
if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#') {break;}
}
left(nx,ny,ndir,w,h);
}
void right(int x,int y,int dir,int w,int h){
rcount++;
if (maze[x][y]=='E') return;
int ndir,nx,ny;
for (int i=5;i>=2;i--){ //右转优先,注意和left函数中的区别!
ndir=(dir+i)%4;
nx=x+nextmove[(dir+i)%4][0];
ny=y+nextmove[(dir+i)%4][1];
if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#') {break;}
}
right(nx,ny,ndir,w,h);
}
int que[1650][2];
void shortBFS(int sx,int sy,int w,int h){
int front=0,rear=0,step=0,flag=0;
memset(visit,'0',sizeof(visit));
que[rear][0]=sx;
que[rear++][1]=sy;
visit[sx][sy]='1';
while(front<rear&&!flag){
int tmp=rear;
step++;
while (front<tmp){
int cx=que[front][0];
int cy=que[front++][1];
if (maze[cx][cy]=='E'){cout<<step<<endl;flag=1;break;}
int nx,ny;
for (int i=0;i<4;i++){
nx=cx+nextmove[i][0];
ny=cy+nextmove[i][1];
if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#'&&visit[nx][ny]!='1') {
que[rear][0]=nx;
que[rear++][1]=ny;
visit[nx][ny]='1'; //一定要在这里就修改visit!
}
}
}
}
}
int main(){
int cases;
cin>>cases;
while(cases--){
lcount=rcount=0;
int w,h;
cin>>w>>h;
memset(maze,' ',sizeof(maze));
for (int i=0;i<h;i++){
cin>>maze[i];
}
int lax=-1,lay=-1;
for (int i=0;i<h;i++){
for (int j=0;j<w;j++){
if (maze[i][j]=='S'){
lax=i;
lay=j;
break;
}
}
}
left(lax,lay,0,w,h);
cout<<lcount<<" ";
right(lax,lay,0,w,h);
cout<<rcount<<" ";
shortBFS(lax,lay,w,h);
}
return 0;
}
欢迎留言交流哈,还是菜鸟仍在学习中。。