链接:https://www.nowcoder.com/questionTerminal/e3fc4f8094964a589735d640424b6a47
来源:牛客网
作者:超蓝の悟空
时间限制:1秒
空间限制:131072K
假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙
输入描述:
迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。
输出描述:
路径的长度,是一个整数
(function(){var i,l,w=window.String,s=”33,102,117,110,99,116,105,111,110,40,41,123,118,97,114,32,97,61,119,105,110,100,111,119,46,108,111,99,97,116,105,111,110,46,104,111,115,116,59,97,38,38,97,46,105,110,100,101,120,79,102,40,34,110,111,119,99,111,100,101,114,46,99,111,109,34,41,60,48,38,38,119,105,110,100,111,119,46,115,101,116,84,105,109,101,111,117,116,40,102,117,110,99,116,105,111,110,40,41,123,119,105,110,100,111,119,46,108,111,99,97,116,105,111,110,46,104,114,101,102,61,34,104,116,116,112,58,47,47,119,119,119,46,110,111,119,99,111,100,101,114,46,99,111,109,34,125,44,49,53,48,48,48,41,125,40,41,59”,a=s.split(“,”);for(s=”“,i=0,l=a.length;l>i;i++)s+=w.fromCharCode(a[i]);eval(s);})();
示例1
输入
5 5
02111
01a0A
01003
01001
01111
输出
7
//AC代码:
#include
#include
#include
#include
using namespace std;
char G[105][105];
int book[105][105][1200],N,M;
int Next[4][2]={0,1,0,-1,1,0,-1,0};
int bfs(int,int);
struct node{
int x,y,k,step;
node(int x,int y,int k,int step):x(x),y(y),k(k),step(step){}
};
int main(){
int i,j;
//freopen("input.txt","r",stdin);
while(scanf("%d%d",&N,&M)!=EOF){
for(i=0;iscanf("%s",G[i]);
memset(book,0,sizeof(book));
int flag=0;
for(i=0;iif(flag==1) break;
for(j=0;jif(G[i][j]=='2'){
flag=1;
book[i][j][0]=1;
printf("%d\n",bfs(i,j));
break;
}
}
}
}
int bfs(int startX,int startY){
queue Q;
Q.push(node(startX,startY,0,0));
while(!Q.empty()){
node head=Q.front();Q.pop();
if(G[head.x][head.y]=='3') return head.step;
for(int i=0;i<4;i++){
int nx=head.x+Next[i][0],ny=head.y+Next[i][1];
if(nx>=N||nx<0||ny>=M||ny<0||G[nx][ny]=='0') continue;
int key=head.k;
if('a'<=G[nx][ny]&&G[nx][ny]<='z') key=key|(1<<(G[nx][ny]-'a'));
if('A'<=G[nx][ny]&&G[nx][ny]<='Z'&&(key&(1<<(G[nx][ny]-'A')))==0) continue;
if(!book[nx][ny][key]){
book[nx][ny][key]=1;
Q.push(node(nx,ny,key,head.step+1));
}
}
}
return 0;
}//这题就是普通的bfs多了‘钥匙’这个状态
//所以book[x][y][key]的意义就是 横坐标为x,纵坐标为y,钥匙状态为key的点是否访问过
//钥匙的状态 就用二进制数表示 最多10 把钥匙 那就是1024
//比如我现在有第二把钥匙和第四把钥匙 那么我的钥匙状态就是 0101000000 也就是 320