题目解析
思路
状态压缩
借鉴状态压缩的思想用一个10位的二进制数表示此刻对10把钥匙的拥有情况。
分析
代码
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct Node{
int x,y,step,key;
Node(){}
Node(int a,int b,int s,int k):x(a),y(b),step(s),key(k){}
};
int sx,sy,ex,ey;
int n,m,t;
char a[25][25];
int d[4][2]={{1,0}, {0, 1}, {-1, 0}, {0, -1}};
int flag[25][25];//墙
int key[25][25];//钥匙
int door[25][25];//门
int vis[25][25][1049];//标记
bool can(int x,int y,int k){//是否可通过
if(x>=0 && x<n && y>=0 && y<m && !flag[x][y]){
if(vis[x][y][k])return false;
if((k & door[x][y])==door[x][y])return true;
}
return false;
}
int bfs(){
memset(vis,0,sizeof(vis));
queue<Node>q;
Node s=Node(sx,sy,0,0);
q.push(s);
vis[sx][sy][0]=1;
while(!q.empty()){
Node e=q.front();
q.pop();
if(e.x==ex && e.y==ey)
return e.step;
for(int i=0;i<4;i++){
int nx=e.x+d[i][0];
int ny=e.y+d[i][1];
if(can(nx,ny,e.key)){
Node nex=Node(nx,ny,e.step+1,e.key|key[nx][ny]);
vis[nx][ny][nex.key]=1;
q.push(nex);
}
}
}
return 0;
}
int main(){
while(~scanf("%d%d%d\n",&n,&m,&t)){
memset(flag,0,sizeof(flag));
memset(door,0,sizeof(door));
memset(key,0,sizeof(key));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%c",&a[i][j]);
if(a[i][j]=='*'){
flag[i][j]=1;
}else if(a[i][j]=='@'){
sx=i;
sy=j;
}else if(a[i][j]=='^'){
ex=i;
ey=j;
}else if(a[i][j]>='a'&&a[i][j]<='z'){
key[i][j]=1<<(a[i][j]-'a');
}else if(a[i][j]>='A'&&a[i][j]<='Z'){
door[i][j]=1<<(a[i][j]-'A');
}
}
getchar();
}
int res=bfs();
if(res<t&&res)
printf("%d\n",res);
else
printf("-1\n");
}
return 0;
}