胜利大逃亡(续) HDU-1429
题目链接
思路:状态压缩+bfs
状态压缩很常用也很简单,网上有很多关于状态压缩的博客,我就不再赘述。因为A-J只有十把钥匙和门,而状态只有找到和没有找到钥匙,利用二进制进行状态压缩。
坑:时间到了则判为失败,而不是被抓回起点。
#include <bits/stdc++.h>
#define maxn 22
using namespace std;
int n,m,t;
char mp[maxn][maxn];
struct node
{
int x,y,s,sta=0;
};
node a,ne;
int dx[]= {-1,0,1,0};
int dy[]= {0,1,0,-1};
int sx,sy;
int vis[maxn][maxn][(1<<10)+10];
bool check()
{
int x=ne.x;
int y=ne.y;
if(x<0||y<0||x>=n||y>=m)
return false;
if(mp[x][y]=='*')
return false;
return true;
}
int bfs()
{
queue<node>q;
a.x=sx;
a.y=sy;
a.sta=0;
a.s=0;
vis[sx][sy][0]=1;
q.push(a);
while(!q.empty())
{
a=q.front();
q.pop();
if(a.s==t)
{
return -1;
}
if(mp[a.x][a.y]=='^')
{
return a.s;
}
for(int i=0; i<4; ++i)
{
ne=a;
ne.x=a.x+dx[i];
ne.y=a.y+dy[i];
if(check()&&!vis[ne.x][ne.y][ne.sta])
{
if(mp[ne.x][ne.y]>='A'&&mp[ne.x][ne.y]<='J')
{
if((ne.sta&(1<<(mp[ne.x][ne.y]-'A')))==0)
{
continue;
}
}
else if(mp[ne.x][ne.y]>='a'&&mp[ne.x][ne.y]<='j')
{
ne.sta|=1<<(mp[ne.x][ne.y]-'a');
}
ne.s++;q.push(ne);
vis[ne.x][ne.y][ne.sta]=true;
}
}
}
return -1;
}
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d%d%d",&n,&m,&t))
{
memset(vis,0,sizeof(vis));
for(int i=0; i<n; ++i)
{
for(int j=0; j<m; ++j)
{
scanf(" %c",&mp[i][j]);
if(mp[i][j]=='@')
{
sx=i,sy=j;
}
}
}
printf("%d\n",bfs());
}
return 0;
}