Escape(多记一个方向状态的BFS)迷宫逃脱

题意:https://www.nitacm.com/problem_show.php?pid=2266

vis记【x】【y】【dir】三个状态就行。

引用:https://blog.csdn.net/qq_37451344/article/details/80243077

  1 #include<string.h>
  2 #include<stdio.h>
  3 #include<queue>
  4 #include<string>
  5 #include<algorithm>
  6 using namespace std;
  7 int x1,y1;
  8 int n,m;
  9 char mat[85][85];
 10 int vis[85][85][4];
 11 int f[4][2]={0,1,0,-1,-1,0,1,0};//左,右,上,下; 
 12 struct node{
 13     int x,y;//坐标 
 14     int ff;//方向 
 15     int temp;
 16 };
 17 int judge(int a,int b,int c,int d)
 18 {//判断符不符合拐弯的条件 
 19     if(mat[a][b]=='#'&&mat[c][d]=='#')
 20     {
 21         return 0;
 22     }
 23     return 1;
 24 }
 25 void bfs()
 26 {
 27     node s,t;
 28     queue<node>q;
 29     s.x=x1;
 30     s.y =y1;
 31     s.temp=0;
 32     s.ff=-1;//起始方向为-1 
 33     vis[x1][y1][0]=vis[x1][y1][1]=vis[x1][y1][2]=vis[x1][y1][3]=1;
 34     q.push(s);
 35     while(!q.empty())
 36     {
 37         int flag=0;
 38         t=q.front();
 39         q.pop();
 40         if((t.x==0||t.x==n-1||t.y==0||t.y==m-1))
 41         {//到达边缘 
 42             printf("%d
",t.temp );
 43             return;
 44         }
 45         int x2,x3,y2,y3;
 46         if(t.ff==0||t.ff==1)
 47         {//当从左,或从右到达t点时,判断上下方向能不能拐弯 
 48             x2=t.x+1;
 49             y2=t.y;
 50             x3=t.x-1;
 51             y3=t.y;
 52             if(judge(x2,y2,x3,y3))
 53             {//如果能拐
 54                 for(int i=2;i<4;i++)
 55                 {//向上或向下拐 
 56                     s.x=t.x+f[i][0];
 57                     s.y=t.y+f[i][1];
 58                     s.temp=t.temp+1;
 59                     s.ff=i;//记录s点从哪个方向过来的 
 60                     if(s.x>=n||s.x<0||s.y>=m||s.y<0||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
 61                         continue;
 62                     vis[s.x][s.y][i]=1;
 63                     q.push(s);    
 64                 }
 65             }
 66             else flag=1;//不能拐,标记 
 67         }
 68             
 69         else if(t.ff==3||t.ff==2)
 70         {//从上或下到达t点时,判断左右方向能不能拐弯 
 71             x2=t.x;
 72             y2=t.y+1;
 73             x3=t.x;
 74             y3=t.y-1;
 75             if(judge(x2,y2,x3,y3))
 76             {//能拐 
 77                 for(int i=0;i<2;i++)
 78                 {//就两个方向,向左或向右拐 
 79                     s.x=t.x+f[i][0];
 80                     s.y=t.y+f[i][1];
 81                     s.temp=t.temp+1;
 82                     s.ff=i;
 83                     if(s.x>=n||s.x<0||s.y>=m||s.y<0||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
 84                         continue;
 85                     vis[s.x][s.y][s.ff]=1;
 86                     q.push(s);
 87                 }
 88             }
 89             else flag=1;//不能拐,标记 
 90         }
 91         
 92         else if(t.ff==-1)
 93         {//这是起点的时候,任意方向都可以 
 94             for(int i=0;i<4;i++)
 95             {
 96                 s.x=t.x+f[i][0];
 97                 s.y=t.y+f[i][1];
 98                 s.temp=t.temp+1;
 99                 s.ff=i;
100                 if(s.x>=n||s.x<0||s.y>=m||s.y<0||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
101                     continue;
102                 vis[s.x][s.y][s.ff]=1;
103                 q.push(s);    
104             }
105         }
106         
107         if(flag==1)
108         {//如果不能拐,就按原方向前进 
109             s.x=t.x+f[t.ff][0];
110             s.y=t.y+f[t.ff][1];
111             s.temp=t.temp+1;
112             s.ff=t.ff;
113             if(s.x>=n||s.x<0||s.y>=m||s.y<0||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
114                 continue;
115             vis[s.x][s.y][s.ff]=1;
116             q.push(s);
117         }
118     }
119     printf("-1
");
120     return;
121 }
122 int main()
123 {
124     int t;
125     scanf("%d",&t);
126     while(t--)
127     {
128         memset(vis,0,sizeof(vis));
129         scanf("%d%d",&n,&m);
130         for(int i=0;i<n;i++)
131             scanf("%s",mat[i]);
132         for(int i=0;i<n;i++)
133             for(int j=0;j<m;j++)
134             {
135                 if(mat[i][j]=='@')
136                 {//起点 
137                     x1=i;y1=j;
138                 }
139             }
140             if(x1==0||x1==n-1||y1==0||y1==m-1)
141             {//起点在边缘,就是0 
142                 printf("0
");
143                 continue;
144             }
145             bfs();
146     }
147     return 0; 
148 }
原文地址:https://www.cnblogs.com/--HPY-7m/p/11808232.html