bfs套一个bfs
先bfs box的移动情况,这里注意的是可能一个坐标x,ybox多次经过是可行的。网上的很多AC代码就没注意这个。比如下面这组数据:
8 9 ######### #......T# #.S.....# ##B###### #.......# #.......# #.......# #########
网上很多AC代码输出“Impossible.”明显错的。。。
然后在每次bfs box的时候bfs person 判断是否能走到相应的点。(即相反的方向点)
最后还注意的是 Output a single blank line after each test case. 如果最后没有空行竟然是报wa的。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <queue> 6 #include <string> 7 8 using namespace std; 9 10 #define MAXN 22 11 char P[4]={'N','S','W','E'}; 12 char M[4]={'n','s','w','e'}; 13 int R,C; 14 int dir[4][2]={-1,0,1,0,0,-1,0,1}; 15 char map[MAXN][MAXN]; 16 struct point 17 { 18 int x,y; 19 int p_x,p_y;//当前状态person所在的地方 20 string ans; 21 }; 22 bool isok(int x,int y) 23 { 24 if(x>=0 && x<R && y>=0 && y<C && map[x][y] != '#') 25 return true; 26 return false; 27 } 28 string tmp; 29 bool bfs_person(point en,point cu) 30 { 31 tmp=""; 32 point st; 33 st.x=en.p_x; 34 st.y=en.p_y; 35 st.ans=""; 36 queue<point>q; 37 bool vis[MAXN][MAXN]; 38 memset(vis,0,sizeof(vis)); 39 while(!q.empty()) 40 q.pop(); 41 q.push(st); 42 while(!q.empty()) 43 { 44 point cur,next; 45 cur=q.front(); 46 q.pop(); 47 if(cur.x==en.x && cur.y==en.y) 48 { 49 tmp=cur.ans; 50 return true; 51 } 52 for(int i=0;i<4;i++) 53 { 54 next=cur; 55 next.x=cur.x+dir[i][0]; 56 next.y=cur.y+dir[i][1]; 57 if(!isok(next.x,next.y)) continue; 58 if(next.x==cu.x && next.y==cu.y) continue; 59 if(vis[next.x][next.y]) continue; 60 vis[next.x][next.y]=1; 61 next.ans=cur.ans+M[i]; 62 q.push(next); 63 } 64 } 65 return false; 66 } 67 string bfs_box() 68 { 69 bool vis[MAXN][MAXN][4];//某点四个方向是否访问!!0==N,1==S,2==W,3==E 70 point st; 71 st.x=st.y=-1; 72 st.p_x=st.p_y=-1; 73 st.ans=""; 74 for(int i=0;i<R && (st.x==-1 || st.p_x==-1);i++) 75 for(int j=0;j<C && (st.x==-1 || st.p_x==-1);j++) 76 if(map[i][j]=='B') 77 { 78 st.x=i; 79 st.y=j; 80 map[i][j]='.'; 81 } 82 else if(map[i][j]=='S') 83 { 84 st.p_x=i; 85 st.p_y=j; 86 map[i][j]='.'; 87 } 88 //---------------------------------------- 89 //cout<<"st.x="<<st.x<<" st.y="<<st.y<<" st.p_x="<<st.p_x<<" st.p_y="<<st.p_y<<endl; 90 //---------------------------------------- 91 queue<point> q; 92 while(!q.empty()) 93 q.pop(); 94 q.push(st); 95 memset(vis,0,sizeof(vis)); 96 while(!q.empty()) 97 { 98 point cur=q.front();q.pop(); 99 //---------------------------------------- 100 // cout<<"cur.x="<<cur.x<<" cur.y="<<cur.y<<" cur.p_x="<<cur.p_x<<" cur.p_y="<<cur.p_y<<endl; 101 // cout<<"-----------------------------\n"; 102 //---------------------------------------- 103 point next,pre; 104 if(map[cur.x][cur.y]=='T') 105 return cur.ans; 106 for(int i=0;i<4;i++) 107 { 108 next=cur; 109 next.x=cur.x+dir[i][0]; 110 next.y=cur.y+dir[i][1]; 111 if(!isok(next.x,next.y)) 112 continue; 113 if(vis[next.x][next.y][i]) 114 continue; 115 pre=cur; 116 switch(i) 117 { 118 case 0: pre.x=cur.x+1;break; 119 case 1: pre.x=cur.x-1;break; 120 case 2: pre.y=cur.y+1;break; 121 case 3: pre.y=cur.y-1;break; 122 } 123 if(!bfs_person(pre,cur))//搜寻人是否能走到特定的位置 124 continue; 125 vis[next.x][next.y][i]=1; 126 next.ans=cur.ans+tmp; 127 next.ans=next.ans+P[i]; 128 next.p_x=cur.x;next.p_y=cur.y; 129 q.push(next); 130 } 131 } 132 return "Impossible."; 133 } 134 135 int main() 136 { 137 int cas=1; 138 while(scanf("%d%d",&R,&C) && (R+C)) 139 { 140 getchar(); 141 for(int i=0;i<R;i++) 142 gets(map[i]); 143 144 //--------------------------------------- 145 // for(int i=0;i<R;i++) 146 // cout<<map[i]<<endl; 147 //---------------------------------------- 148 149 printf("Maze #%d\n",cas++); 150 //printf("%s\n",bfs_box()); 151 cout<<bfs_box()<<endl<<endl; 152 } 153 return 0; 154 }