#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
int n,m,t;
bool vis[21][21][1025];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
char e[21][21];
struct node{
int x,y,step,w;
}b;
queue<node>q;
int bfs(node a)
{
memset(vis,false,sizeof(vis));
a.step=a.w=0;
vis[a.x][a.y][0]=true;
while(!q.empty())q.pop();
int i,j,k,xx,yy,step,w;
q.push(a);
while(!q.empty())
{
a=q.front();
q.pop();
if(a.step>=t-1)return -1;
for(i=0;i<4;i++)
{
xx=a.x+dir[i][0];
yy=a.y+dir[i][1];
step=a.step+1;
w=a.w;
//汗,这里忘了vis,超内存,我还以为是我队列的缘故呢。。
if(xx<0||yy<0||xx>=n||yy>=m||e[xx][yy]=='*'||vis[xx][yy][w])continue;
if(e[xx][yy]=='^')return step;
if(e[xx][yy]>='A'&&e[xx][yy]<='J')
{
j=e[xx][yy]-'A';
if(((1<<j)&w)&&!vis[xx][yy][w])
{
vis[xx][yy][w]=true;
b.x=xx;b.y=yy;b.step=step;b.w=w;
q.push(b);
}
}
else if(e[xx][yy]>='a'&&e[xx][yy]<='j')
{
j=e[xx][yy]-'a';
w=w|(1<<j);
if(!vis[xx][yy][w])
{
vis[xx][yy][w]=true;
b.x=xx;b.y=yy;b.step=step;b.w=w;
q.push(b);
}
}
else
{
vis[xx][yy][w]=true;
b.x=xx;b.y=yy;b.step=step;b.w=w;
q.push(b);
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
int i,j,k;
node a;
for(i=0;i<n;i++)
scanf("%s",e[i]);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
if(e[i][j]=='@'){a.x=i;a.y=j;}
}
printf("%d\n",bfs(a));
}
return 0;
}
/*
状态压缩+bfs题
vis[i][j][k]标记坐标为(i,j),钥匙状态为k(用10位二进制表示,每位对应一把钥匙)的状态。
遇到牢门时,判断下钥匙状态中是否有钥匙。
遇到钥匙时,改变钥匙状态
*/
hdu 1429 胜利大逃亡(续) bfs+状态压缩
最新推荐文章于 2020-11-17 21:13:01 发布