题意:
有一个迷宫,题目给出了起始位置,让我们分别求出始终贴着左墙和右墙以及从起点到终点最小的步数。
思路:
最少步数好求,直接bfs即可。难就难在两个深搜上面。我们在深搜的时候用face记录现在在朝哪个方向,对于不同方向,按不同顺序走,然后再根据此方向来确定下一步,是继续走还是转弯!
代码:
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <cstring> #include <queue> using namespace std; int w,h,flag; int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; bool vis[101][101]; struct node{ int x,y; int moves; }; int ansl,ansr; int mp[101][101]; int sx,sy,ex,ey; void dfsl(int x,int y,int step,int face) //沿着左,1是往左,2是往上,3是往右,4是往下 { if(flag==1)return; if(x==ex&&y==ey){flag=1;ansl=step;return;} if(face == 1){ //往左,则下面是墙,优先搜索 下,左,上,右 if(mp[x+1][y]) dfsl(x+1,y,step+1,4); if(mp[x][y-1]) dfsl(x,y-1,step+1,1); if(mp[x-1][y]) dfsl(x-1,y,step+1,2); if(mp[x][y+1]) dfsl(x,y+1,step+1,3); } else if(face == 2){ //往上,则左面是墙,优先搜索 左 ,上,右,下 if(mp[x][y-1]) dfsl(x,y-1,step+1,1); if(mp[x-1][y]) dfsl(x-1,y,step+1,2); if(mp[x][y+1]) dfsl(x,y+1,step+1,3); if(mp[x+1][y]) dfsl(x+1,y,step+1,4); } else if(face == 3){ //往右,则上面是墙,优先搜索 上,右,下,左 if(mp[x-1][y]) dfsl(x-1,y,step+1,2); if(mp[x][y+1]) dfsl(x,y+1,step+1,3); if(mp[x+1][y]) dfsl(x+1,y,step+1,4); if(mp[x][y-1]) dfsl(x,y-1,step+1,1); } else{ if(mp[x][y+1]) dfsl(x,y+1,step+1,3); //下,则右面是墙,优先搜索 右,下,左,上 if(mp[x+1][y]) dfsl(x+1,y,step+1,4); if(mp[x][y-1]) dfsl(x,y-1,step+1,1); if(mp[x-1][y]) dfsl(x-1,y,step+1,2); } } void dfsr(int x,int y,int step,int face) //沿着右,1是往左,2是往上,3是往右,4是往下{ if(flag==1)return; if(x==ex&&y==ey){flag=1;ansr=step;return;} if(face == 1){ //沿着左,则上面是墙,优先搜索 上 ,左,下,右 if(mp[x-1][y]) dfsr(x-1,y,step+1,2); if(mp[x][y-1]) dfsr(x,y-1,step+1,1); if(mp[x+1][y]) dfsr(x+1,y,step+1,4); if(mp[x][y+1]) dfsr(x,y+1,step+1,3); } else if(face == 2){ //沿着上,则右边是墙,优先搜索 右,上,左,下 if(mp[x][y+1]) dfsr(x,y+1,step+1,3); if(mp[x-1][y]) dfsr(x-1,y,step+1,2); if(mp[x][y-1]) dfsr(x,y-1,step+1,1); if(mp[x+1][y]) dfsr(x+1,y,step+1,4); } else if(face == 3){ //沿着右,则下面是墙,优先搜索 下,右,上,左 if(mp[x+1][y]) dfsr(x+1,y,step+1,4); if(mp[x][y+1]) dfsr(x,y+1,step+1,3); if(mp[x-1][y]) dfsr(x-1,y,step+1,2); if(mp[x][y-1]) dfsr(x,y-1,step+1,1); } else{ //沿着下走,则左面是墙,优先搜索 左,下,右,上 if(mp[x][y-1]) dfsr(x,y-1,step+1,1); if(mp[x+1][y]) dfsr(x+1,y,step+1,4); if(mp[x][y+1]) dfsr(x,y+1,step+1,3); if(mp[x-1][y]) dfsr(x-1,y,step+1,2); }}int bfs() //求最短路径{ queue<node>q; vis[sx][sy]=1; node t,tt,start; start.x=sx; start.y=sy; start.moves=1; q.push(start); int sum; while(!q.empty()) { t=q.front(); q.pop(); if(t.x== ex && t.y==ey){ sum=t.moves; } for(int i=0;i<4;i++) { int xxx=t.x+dir[i][0]; int yyy=t.y+dir[i][1]; if(mp[xxx][yyy]==1&&!vis[xxx][yyy]&&xxx>=1&&xxx<=h&&yyy>=1&&yyy<=w){vis[xxx][yyy]=1;tt.x=xxx,tt.y=yyy,tt.moves=t.moves+1;q.push(tt);} } } return sum;}int main(){ //freopen("D:/a.txt","r",stdin); int t; int i,j; char str[50]; cin>>t; while(t--) { memset(mp,0,sizeof(mp)); cin>>w>>h; getchar(); for(i=1;i<=h;i++) { gets(str); for(j=0;j<w;j++) { if(str[j]=='S'){mp[i][j+1]=1;sx=i,sy=j+1;} if(str[j]=='E'){mp[i][j+1]=1;ex=i,ey=j+1;} if(str[j]=='.'){mp[i][j+1]=1;} } } memset(vis,0,sizeof(vis)); flag=0;dfsl(sx,sy,1,1); flag=0;dfsr(sx,sy,1,1); cout<<ansl<<' '<<ansr<<' '; cout<<bfs()<<endl; } return 0;} 心得:花费了好几个小时。。。能力不足啊