题意:给你一个迷宫,入口处标为S,出口处标为E,可以走的地方为“.”,不可以走的地方为#,求左转优先时从出口到入口的路程,再求右转优先时,出口到入口的路程,最后求从出口到入口的最短路程。
思路:求前两个的时候用DFS递归求解能走的路就OK,求最短的时候当然要用广度优先搜索啦。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std ; 5 char ch[158][158]; 6 int sum ;//总步数 7 int h,w,i,j,k ; 8 int enx,eny,stax,stay; 9 int fx[] = {0,1,0,-1};//列的变化,从0开始顺时针变化 10 int fy[] = {1,0,-1,0};//行的变化,从0开始顺时针变化 11 int lef[] = {1,0,3,2};//左转优先时,标记上下左右4个方向分别为0213; 12 int rig[] = {3,0,1,2};//右转优先时,右边为1; 13 struct node 14 { 15 int xz,yz; 16 int cnt; 17 } sh[10001];//数组模拟队列 18 void DFS(int dire,int x,int y,int d)//这个点的初始方向,这个点现在坐标,以及是左先还是右先 19 { 20 if(x == enx&&y == eny)//如果遍历到了'E'所在坐标,就结束掉遍历,返回 21 { 22 printf("%d",sum); 23 return ; 24 } 25 int xx,yy; 26 sum++; 27 if(d == 1)//左转优先 28 { 29 for(i = 0 ; i <= 3 ; i++)//4个方向遍历一遍 30 { 31 j = (dire+lef[i])%4;//求出当前位置的方向数字 32 xx = x+fx[j];//传过来的参数x为原来的坐标j 33 yy = y+fy[j]; 34 if(xx>=0&&xx< h&&yy>=0&&yy< w&&ch[yy][xx] != '#')//继续遍历的条件是不为#且没越出边界,要注意xx是到h为边界的与主函数中对应 35 { 36 DFS(j,xx,yy,1);//继续递归下去 37 return ; 38 } 39 } 40 } 41 else 42 { 43 for(i = 0 ; i <= 3 ; i++) 44 { 45 j = (dire+rig[i])%4; 46 xx = x+fx[j]; 47 yy = y+fy[j]; 48 if(xx>=0 && xx < h&&yy>=0 && yy < w&&ch[yy][xx] != '#') 49 { 50 DFS(j,xx,yy,0); 51 return ; 52 } 53 } 54 } 55 } 56 void BFS(int x,int y)//广度优先搜索是队列,深度优先搜索是栈,深度是递归 57 { 58 int zh[158][158] = {0};//标记数组,初始化为0,表示节点未被访问过 59 int le = 0,ri = 1 ; 60 zh[y][x] = 1; 61 //将当前点坐标压入队列,后边进行处理 62 sh[0].xz = x; 63 sh[0].yz = y ; 64 sh[0].cnt = 1 ; 65 while(le < ri) 66 { 67 x = sh[le].xz;//从队列中取出进行操作 68 y = sh[le].yz ; 69 sum = sh[le++].cnt; 70 for(k = 0 ; k <= 3 ; k++) 71 { 72 //点的坐标 73 i = y+fy[k]; 74 j = x+fx[k]; 75 if(i>=0 && i<w && j<h && j>=0 && !zh[i][j] &&ch[i][j]!='#')//在原有条件下,还要保证节点没有被访问过 76 { 77 if(j == enx&&i == eny)//如果找到'E'就输出长度 78 { 79 cout<<sum+1<<endl; 80 return ; 81 } 82 zh[i][j] = 1;//表示这个节点已经被访问过了,标记为1 83 //将这个点加入队列用来以后进行访问这个点四周的点 84 sh[ri].yz = i; 85 sh[ri].xz = j; 86 sh[ri].cnt = sum+1;//这个点步数加1 87 ri++;//while循环结束的条件就是该点不符合条件,ri不再累加 88 } 89 } 90 } 91 } 92 int main() 93 { 94 int n,dire; 95 scanf("%d",&n); 96 while(n--) 97 { 98 scanf("%d %d",&h,&w);//h是列,w是行 99 for(i = 0 ; i <= w-1 ; i++) 100 { 101 scanf("%s",ch[i]); 102 for(j = 0 ; j <= h-1 ; j++) 103 { 104 if(ch[i][j] == 'S') 105 { 106 stax = j; 107 stay = i; 108 } 109 if(ch[i][j] == 'E') 110 { 111 enx = j; 112 eny = i ; 113 } 114 } 115 } 116 if(stax == 0) dire = 1;//左 117 if(stax == h-1) dire = 3;//右 118 if(stay == 0) dire = 0;//上 119 if(stay == w-1) dire = 2 ;//下 120 sum = 1;//初始化 121 DFS(dire,stax,stay,1);//左转优先 122 printf(" "); 123 sum = 1 ;//初始化 124 DFS(dire,stax,stay,0);//右转优先 125 printf(" "); 126 BFS(stax,stay);//求最短的用bfs 127 } 128 return 0; 129 }