题目描述:
链接:https://www.nowcoder.com/questionTerminal/e3fc4f8094964a589735d640424b6a47
来源:牛客网
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
思路分析:
用到了bfs和状态压缩。
代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<iostream> 4 #include<vector> 5 #include<algorithm> 6 #include<queue> 7 #include<string.h> 8 using namespace std; 9 10 int n,m,sx,sy,ex,ey; 11 char g[1024][1024]; 12 int use[120][120][1400]; 13 int dx[]={0,0,1,-1}; 14 int dy[]={1,-1,0,0}; 15 struct node 16 { 17 int x,y,k; 18 }; 19 20 int bfs() 21 { 22 memset(use,0xff,sizeof(use)); 23 queue<node>q; 24 node t; 25 t.x=sx; 26 t.y=sy; 27 t.k=0; 28 use[t.x][t.y][t.k]=0; 29 q.push(t); 30 while(!q.empty()) 31 { 32 t = q.front(); 33 q.pop(); 34 //printf("%d %d %d %d ",t.x,t.y,t.k,use[t.x][t.y][t.k]); 35 if(t.x==ex&&t.y==ey) return use[t.x][t.y][t.k]; 36 for(int i=0;i<4;i++)//上下左右 37 { 38 node k;//分别往上下左右走 39 k.x = t.x + dx[i]; 40 k.y = t.y + dy[i]; 41 k.k = t.k; 42 if(k.x<0||k.x>=n||k.y<0||k.y>=m||g[k.x][k.y]=='0') continue;//直接进入下次循环 43 if(g[k.x][k.y]>='a'&&g[k.x][k.y]<='z') 44 { 45 k.k = k.k|(1<<(g[k.x][k.y]-'a'));//走到钥匙点捡起钥匙 46 } 47 if(g[k.x][k.y]>='A'&&g[k.x][k.y]<='Z') 48 { 49 int p = k.k&(1<<(g[k.x][k.y]-'A'));//走到门处匹配钥匙 50 if(p==0) continue;//没有钥匙直接进入下次循环 51 } 52 if(use[k.x][k.y][k.k]==-1||use[k.x][k.y][k.k]>use[t.x][t.y][t.k]+1)//第一个条 件保证BFS,第二个条件保证不走墙 53 { 54 use[k.x][k.y][k.k]=use[t.x][t.y][t.k]+1; 55 q.push(k); 56 } 57 } 58 } 59 return -1; 60 } 61 62 int main() 63 { 64 scanf("%d%d",&n,&m); 65 for(int i=0; i<n; i++) 66 { 67 scanf("%s",g[i]); 68 for(int j=0; j<m; j++) 69 { 70 if(g[i][j] == '2') 71 { 72 sx = i; 73 sy = j; 74 } 75 if(g[i][j] == '3') 76 { 77 ex = i; 78 ey = j; 79 } 80 } 81 } 82 printf("%d ",bfs()); 83 return 0; 84 }