迷宫问题,有钥匙和门的 bfs + 状态压缩
有四个钥匙四把锁,求最短路径
具体解释都在代码里面,可以多看一下,并且和下一边状态压缩问题一起对应这看一下比较好。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; #define MAXN 110 struct Node { int x,y,key; int step; }; char map[MAXN][MAXN]; //地图 bool mark[MAXN][MAXN][22];//标记是否访问 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //方向 int n,m; Node st; char Door[4]={'B','Y','R','G'}; char Key[4]={'b','y','r','g'}; void bfs() { memset(mark,false,sizeof(mark)); queue<Node>Q; Node p,q; st.key=st.step=0; mark[st.x][st.y][st.key]=true; Q.push(st); while(!Q.empty()){ p=Q.front(); Q.pop(); if(map[p.x][p.y]=='X'){ printf("Escape possible in %d steps.\n",p.step); return ; } for(int i=0;i<4;i++) { q.x=p.x+dir[i][0]; q.y=p.y+dir[i][1]; q.step=p.step+1; q.key=p.key; if(q.x<1||q.x>n||q.y<1||q.y>m||map[q.x][q.y]=='#') continue; if(isupper(map[q.x][q.y])&&map[q.x][q.y]!='X') {//isupper判断是否是大写字母(锁的位置) for(int j=0;j<4;j++) { if(map[q.x][q.y]==Door[j]) //找是哪个锁 { if(q.key&(1<<j)) //q.key,是否有该锁的钥匙 {//没有 if(!mark[q.x][q.y][q.key]) { mark[q.x][q.y][q.key]=true; Q.push(q); } break; } } } } else if(islower(map[q.x][q.y])) {//islower()判断是否是小写字母(钥匙的位置) for(int j=0;j<4;j++) { if(map[q.x][q.y]==Key[j]) //找是哪个钥匙 { if((q.key&(1<<j))==0) { q.key+=(1<<j); //加上这把钥匙(标记这个钥匙的状态) } if(!mark[q.x][q.y][q.key]) { mark[q.x][q.y][q.key]=true; Q.push(q); } } } } else { if(!mark[q.x][q.y][q.key]) { mark[q.x][q.y][q.key]=true; Q.push(q); } } } } puts("The poor student is trapped!"); } int main(){ while(scanf("%d%d",&n,&m),(n+m)) { for(int i=1;i<=n;i++) { scanf("%s",map[i]+1); for(int j=1;j<=m;j++) { if(map[i][j]=='*') { st.x=i;st.y=j; } } } bfs(); } return 0; }