Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6630 | Accepted: 2891 |
Description
Input
Output
Sample Input
2 8 8 ######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E#### 9 5 ######### #.#.#.#.# S.......E #.#.#.#.# #########
Sample Output
37 5 5 17 17 9
转自:http://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122369.html
题目大意:
给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走
先输出左转优先时,从S到E的步数
再输出右转优先时,从S到E的步数
最后输出S到E的最短步数
W为宽,列数
H为高,行数
解题思路:
DFS和BFS的综合题水题,难度不大,但是写代码时要注意几方面:
1、 左转、右转优先搜索时必须标记当前位置时的方向,我定义的方向是
最初的方向由起点S确定,而下一步的方向则由前一步的走向决定
例如 左边优先搜索:
当前位置的方向指向 1(向左),(这同时说明前一步是在第“3”的位置走过来的)
那么走下一步时,就要根据2103的顺序,先逐格确定当前位置周边的四格是否可行
若第一次确认2可行,就走到2,在位置2时的方向为2(向下)
若2不可行,则再确定1,若1可行,就走到1,在位置1时的方向为1(向左)
若1也不可行,则再确定0,若0可行,就走到0,在位置0时的方向为0(向上)
若0也不可行,说明进入了迷宫的死胡同,要从原路返回,走回3
右边优先搜索也同理。
根据我定义的方向,设当前位置为d,那么
左转,用数学式子表达就是 d=(d+1)%4
右转,用数学式子表达就是 d=(d+3)%4
我比较懒,在我的程序中,DFS和BFS都用了多入口的做法,有兴趣的同学可以利用我给出的这两个式子对代码进行优化。
这里有一点必须要注意的:
左边、右边优先搜索都不是找最短路,因此走过的路可以再走,无需标记走过的格
2、 寻找最短路只能用BFS
因此在做第3问时别傻乎乎的又用DFS,DFS对于样例的输入确实和BFS得到的结果一样的,别以为样例PASS就提交了。。。所以我就说样例没代表性,学会测试数据很重要= =
注意有一点:
要求E的最短路,必须把迷宫模拟为树,S为根,找到E所在的层(树深),该层就是S到E的最短路,处理技巧就是在BFS时,令queue[tail]的depth等于对应的queue[head]的depth+1,详细见我的程序
把循环的次数作为深度就铁定错的
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 using namespace std; 5 6 struct M{ 7 int r,c; 8 int depth; 9 }; 10 11 M s,e; 12 int Lstep,Rstep; //左/右优先的步数 13 14 bool maze[41][41]; 15 16 void DFS_L(int i,int j,int d) //左边优先搜索, i,j是当前坐标,d为位置方向 17 { 18 Lstep++; 19 if(i==e.r && j==e.c) 20 { 21 return ; 22 } 23 switch(d) //由图可以看出 24 { 25 case 0: 26 { 27 if(maze[i][j-1]) 28 DFS_L(i,j-1,1); 29 else if(maze[i-1][j]) 30 DFS_L(i-1,j,0); 31 else if(maze[i][j+1]) 32 DFS_L(i,j+1,3); 33 else if(maze[i+1][j]) 34 DFS_L(i+1,j,2); 35 break; 36 } 37 case 1: 38 { 39 if(maze[i+1][j]) 40 DFS_L(i+1,j,2); 41 else if(maze[i][j-1]) 42 DFS_L(i,j-1,1); 43 else if(maze[i-1][j]) 44 DFS_L(i-1,j,0); 45 else if(maze[i][j+1]) 46 DFS_L(i,j+1,3); 47 break; 48 } 49 case 2: 50 { 51 if(maze[i][j+1]) 52 DFS_L(i,j+1,3); 53 else if(maze[i+1][j]) 54 DFS_L(i+1,j,2); 55 else if(maze[i][j-1]) 56 DFS_L(i,j-1,1); 57 else if(maze[i-1][j]) 58 DFS_L(i-1,j,0); 59 break; 60 } 61 case 3: 62 { 63 if(maze[i-1][j]) 64 DFS_L(i-1,j,0); 65 else if(maze[i][j+1]) 66 DFS_L(i,j+1,3); 67 else if(maze[i+1][j]) 68 DFS_L(i+1,j,2); 69 else if(maze[i][j-1]) 70 DFS_L(i,j-1,1); 71 break; 72 } 73 } 74 return ; 75 } 76 77 void DFS_R(int i,int j,int d) 78 { 79 Rstep++; 80 if(i==e.r && j==e.c) 81 return; 82 switch(d) 83 { 84 case 0: 85 { 86 if(maze[i][j+1]) 87 DFS_R(i,j+1,3); 88 else if(maze[i-1][j]) 89 DFS_R(i-1,j,0); 90 else if(maze[i][j-1]) 91 DFS_R(i,j-1,1); 92 else if(maze[i+1][j]) 93 DFS_R(i+1,j,2); 94 break; 95 } 96 case 1: 97 { 98 if(maze[i-1][j]) 99 DFS_R(i-1,j,0); 100 else if(maze[i][j-1]) 101 DFS_R(i,j-1,1); 102 else if(maze[i+1][j]) 103 DFS_R(i+1,j,2); 104 else if(maze[i][j+1]) 105 DFS_R(i,j+1,3); 106 break; 107 } 108 case 2: 109 { 110 if(maze[i][j-1]) 111 DFS_R(i,j-1,1); 112 else if(maze[i+1][j]) 113 DFS_R(i+1,j,2); 114 else if(maze[i][j+1]) 115 DFS_R(i,j+1,3); 116 else if(maze[i-1][j]) 117 DFS_R(i-1,j,0); 118 break; 119 } 120 case 3: 121 { 122 if(maze[i+1][j]) 123 DFS_R(i+1,j,2); 124 else if(maze[i][j+1]) 125 DFS_R(i,j+1,3); 126 else if(maze[i-1][j]) 127 DFS_R(i-1,j,0); 128 else if(maze[i][j-1]) 129 DFS_R(i,j-1,1); 130 break; 131 } 132 } 133 return; 134 } 135 136 void BFS(int i, int j) // i,j为起始位置 137 { 138 bool vis[41][41]={false}; 139 M queue[1605]; 140 int head,tail; 141 head=tail=0; 142 queue[0].r=i; 143 queue[0].c=j; 144 queue[tail++].depth=1; 145 vis[i][j]=true; 146 147 while(head<tail) 148 { 149 M x=queue[head++]; 150 if(x.r==e.r && x.c==e.c) 151 { 152 printf("%d\n",x.depth); 153 return; 154 } 155 if(maze[x.r][x.c-1] && !vis[x.r][x.c-1]) 156 { 157 vis[x.r][x.c-1]=true; 158 queue[tail].r=x.r; 159 queue[tail].c=x.c-1; 160 queue[tail++].depth=x.depth+1; 161 } 162 if(maze[x.r-1][x.c] && !vis[x.r-1][x.c]) 163 { 164 vis[x.r-1][x.c]=true; 165 queue[tail].r=x.r-1; 166 queue[tail].c=x.c; 167 queue[tail++].depth=x.depth+1; 168 } 169 if(maze[x.r][x.c+1] && !vis[x.r][x.c+1]) 170 { 171 vis[x.r][x.c+1]=true; 172 queue[tail].r=x.r; 173 queue[tail].c=x.c+1; 174 queue[tail++].depth=x.depth+1; 175 } 176 if(maze[x.r+1][x.c] && !vis[x.r+1][x.c]) 177 { 178 vis[x.r+1][x.c]=true; 179 queue[tail].r=x.r+1; 180 queue[tail].c=x.c; 181 queue[tail++].depth=x.depth+1; 182 } 183 184 } 185 return; 186 } 187 188 int main() 189 { 190 int t; 191 int i,j; 192 scanf("%d",&t); 193 while(t--) 194 { 195 int dir; 196 int w,h; 197 scanf("%d%d",&w,&h); 198 Lstep=1; 199 Rstep=1; 200 memset(maze,false,sizeof(maze)); 201 202 for(i=1;i<=h;i++) 203 { 204 for(j=1;j<=w;j++) 205 { 206 char tt; 207 cin>>tt; 208 if(tt=='.') 209 maze[i][j]=true; 210 if(tt=='S') 211 { 212 maze[i][j]=true; 213 s.r=i; 214 s.c=j; 215 if(i==h) dir=0; //判断其实dir方向 216 else if(j==w) dir=1; 217 else if(i==1) dir=2; 218 else if(j=1) dir=3; 219 } 220 if(tt=='E') 221 { 222 maze[i][j]=true; 223 e.r=i; 224 e.c=j; 225 } 226 227 } 228 } 229 switch(dir) 230 { 231 case 0: {DFS_L(s.r-1,s.c,0);break;} // 题目描述,所有S两边都是'#'。 232 case 1: {DFS_L(s.r,s.c-1,1);break;} 233 case 2: {DFS_L(s.r+1,s.c,2);break;} 234 case 3: {DFS_L(s.r,s.c+1,3);break;} 235 } 236 cout<<Lstep<<' '; 237 238 switch(dir) 239 { 240 case 0: {DFS_R(s.r-1,s.c,0);break;} 241 case 1: {DFS_R(s.r,s.c-1,1);break;} 242 case 2: {DFS_R(s.r+1,s.c,2);break;} 243 case 3: {DFS_R(s.r,s.c+1,3);break;} 244 } 245 cout<<Rstep<<' '; 246 247 BFS(s.r,s.c); 248 } 249 return 0; 250 }