题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429
题目大意:逃离迷宫,但是迷宫里有钥匙和门
题目思路:
关于状态压缩:
1.判断一个数字x二进制下第i位是不是等于1。
方法:if ( ( ( 1 << ( i - 1 ) ) & x ) > 0)
将1左移i-1位,相当于制造了一个只有第i位上是1,其他位上都是0的二进制数。然后与x做与运算,如果结果>0,说明x第i位 上是1,反之则是0。
2.将一个数字x二进制下第i位更改成1。
方法:x = x | ( 1<<(i-1) )
证明方法与1类似,此处不再重复证明。
3.把一个数字二进制下最靠右的第一个1去掉。
方法:x=x&(x-1)
题目:
因为一共只有十把钥匙,所以含有的状态较小,故可以使用状态压缩的方法储存是否拿到钥匙,那么visit数组就变成了 visit[x][y][状态],状态用二进制来表示,然后再用bfs进行处理就能较快速的完成这个问题。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,m,t;
char mmap[21][21];
bool visit[21][21][2049];
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int sx,sy,ex,ey;
struct node
{
int x,y,s;//s表示状态
int step;
};
queue<node>Q;
int bfs()
{
while(!Q.empty()) Q.pop();
memset(visit,0,sizeof(visit));
node a,now,next;
a.x=sx,a.y=sy,a.s=0,a.step=0;
visit[a.x][a.y][0]=1;
Q.push(a);
while(!Q.empty()){
now = Q.front(),Q.pop();
for(int i=0;i<4;i++){
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
next.s=now.s;
next.step=now.step+1;
if(next.x==ex&&next.y==ey) return next.step;
if(next.x<0||next.x>=n||next.y<0||next.y>=m) continue;
if(mmap[next.x][next.y]=='*') continue;
if(visit[next.x][next.y][next.s]) continue;
if(mmap[next.x][next.y]>='A'&&mmap[next.x][next.y]<='Z'){
int key=mmap[next.x][next.y]-'A'+1;
if((next.s>>(key-1))&1){
Q.push(next);
visit[next.x][next.y][next.s]=1;
}
else continue;
}
if(mmap[next.x][next.y]>='a'&&mmap[next.x][next.y]<='z'){
int nkey=mmap[next.x][next.y]-'a'+1;
next.s=(next.s|(1<<(nkey-1)));
if(!visit[next.x][next.y][next.s]){
visit[next.x][next.y][next.s]=1;
Q.push(next);
}
else continue;
}
if(mmap[next.x][next.y]=='.'){
if(!visit[next.x][next.y][next.s]){
visit[next.x][next.y][next.s]=1;
Q.push(next);
}
else continue;
}
if(mmap[next.x][next.y]=='@'){
if(!visit[next.x][next.y][next.s]){
visit[next.x][next.y][next.s]=1;
Q.push(next);
}
else continue;
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&t)){
for(int i=0;i<n;i++){
getchar();
for(int j=0;j<m;j++){
scanf("%c",&mmap[i][j]);
if(mmap[i][j]=='@') sx=i,sy=j;
if(mmap[i][j]=='^') ex=i,ey=j;
}
}
printf("%d\n",bfs()<t?bfs():-1);
getchar();
}
}