一个让我想死的题目,怎么想都没有想到这个题要用广度优先搜索。而且,题目说了,能左转走,能右转走,不能倒着走。妹的,最后一想,我转2次方向,就面向背面了,相当于“往后转”。而且,“走”,和“转”要分开。
1、输入地图,初始化相关存储变量。
2、广度优先搜索,注意状态记录,“走”,和“转”要分开。
3、输出结果,判断搜索情况,搜索是否成功。
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #define size 27 //最大范围25 using namespace std; int n,m; int sx,sy,ex,ey; //起始点,终点坐标 int map[size][size]; //存储地图信息,“-1”不能走,“1”能走 bool flag[size][size][5][4]; //存储搜索状态信息,状态标记【x坐标】【y坐标】【颜色】【方向】 int dir[4][2]={1,0,0,1,-1,0,0,-1}; //四个搜索方向 struct node //节点信息结构体 { int x; //坐标 int y; int step; int time; //耗时 int dict; //方向 int color; //颜色 bool operator <(const node &a)const{ //优先队列,时间小的优先 return time>a.time; } }e,s; void initial() //信息初始化 { char x[size]; //临时存储地图信息 int i,j; memset(map,-1,sizeof(map)); //地图信息初始化,不能走 memset(flag,false,sizeof(flag)); //状态标记数组初始化,所有情况都未遍历 for(i=0;i<n;i++) //输入处理地图信息 { cin>>x; for(j=0;j<m;j++) { if(x[j]=='.')map[i][j]=0; //此处可走 else if(x[j]=='S')sx=i,sy=j,map[i][j]=0; //起始点 else if(x[j]=='T')ex=i,ey=j,map[i][j]=0; //终点 } } } bool inmap(int x,int y) //(x,y)点是否在地图(有效)范围内 { return x>=0&&x<n&&y>=0&&y<m; } int bfs() //广度优先搜索寻路 { int i,j; priority_queue<node> q; s.x=sx; //其实节点初始化 s.y=sy; s.time=0; s.step=0; s.dict=2; //起始方向朝北,根据个人方向数组资料,数据不尽相同 s.color=0; //管它开始什么颜色,方正总共只有5种颜色,最后停下来的时候,还是这个颜色(编号数字相同)就好了 flag[sx][sy][0][2]=true; q.push(s); while(!q.empty()) { s=q.top(); q.pop(); for(i=0;i<4;i++) //四个方向搜索 { e.x=s.x+dir[i][0]; e.y=s.y+dir[i][1]; e.time=s.time+1; e.step=s.step+1; e.dict=i; e.color=(s.color+1)%5; if(!inmap(e.x,e.y)||map[e.x][e.y]==-1) continue; //该点不在地图内,该点不可处理 if(e.dict!=s.dict) //方向不同,先转向,不要急着走格子 { if(e.dict==s.dict+2||e.dict==s.dict-2)e.time++; //反向,要转2次 e.color=s.color; e.x=s.x; //位置不变,颜色不变 e.y=s.y; } if(flag[e.x][e.y][e.color][e.dict]) continue; //这个状态以前走过,不再处理 flag[e.x][e.y][e.color][e.dict]=true; //要处理,标记 if(e.x==ex&&e.y==ey&&e.color==0)return e.time; //走到终点,颜色符合要求,搜索成功 map[e.x][e.y]=e.step; q.push(e); } } return -1; //搜索失败 } int main() { int j=1; while(cin>>n>>m&&n+m) { initial(); //信息初始化 int ans= bfs(); //广度优先搜索得答案 if(j!=1)cout<<endl; //案例中间有空行 cout<<"Case #"<<j++<<endl; if(ans==-1)cout<<"destination not reachable"<<endl; //搜索失败 else cout<<"minimum time = "<<ans<<" sec"<<endl; //搜索成功 } return 0; }
转载于:https://blog.51cto.com/huahua520amy/1373622