hdu_1429_胜利大逃亡(续)(BFS状压)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1429

题意:迷宫的加强版,迷宫里有钥匙和门,问在指定的时间下能否逃出

题解:用二进制位来记录是否有该门的钥匙,然后上BFS

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 #define FFC(i,a,b) for(int i=a;i<=b;i++)
 5 using namespace std;
 6 int n,m,t,j,sx,sy,d[][2]={1,0,-1,0,0,1,0,-1};bool v[22][22][1025];char g[22][22];
 7 struct dt{int x,y,tm,key;};//用二进制位来压缩状态
 8 bool check(int x,int y){if(x<1||x>n||y<1||y>m||g[x][y]=='*')return 0;return 1;}
 9 int fuck(){
10     dt s,o;s.x=sx,s.y=sy,s.tm=0,s.key=0;
11     memset(v,0,sizeof(v));
12     queue<dt>Q;Q.push(s);
13     while(!Q.empty()){
14         o=Q.front();Q.pop();
15         if(g[o.x][o.y]=='^'&&o.tm<t)return o.tm;
16         if(o.tm>t)continue;
17         for(int i=0;i<4;i++){
18             int xx=o.x+d[i][0],yy=o.y+d[i][1],kkey=o.key;
19             if(!check(xx,yy))continue;//检测边界
20             if(g[o.x][o.y]>='A'&&g[o.x][o.y]<='Z'&&!((o.key>>(g[o.x][o.y]-'A'))&1))continue;//检测能否打开门
21             if(g[xx][yy]>='a'&&g[xx][yy]<='z')kkey|=(1<<(g[xx][yy]-'a'));//拣钥匙
22             if(v[xx][yy][kkey])continue;//判断在有这些钥匙的情况下是否搜过该点
23             s.x=xx,s.y=yy,s.tm=o.tm+1,s.key=kkey,v[xx][yy][kkey]=1;
24             Q.push(s);
25         }
26     }
27     return -1;
28 }
29 int main(){
30     while(~scanf("%d%d%d",&n,&m,&t)){
31         FFC(i,1,n){
32             getchar();
33             for(j=1;j<=m;j++){scanf("%c",&g[i][j]);if(g[i][j]=='@')sx=i,sy=j;}
34         }
35         printf("%d\n",fuck());
36     }
37     return 0;
38 }
View Code

 



 

posted @ 2016-05-14 01:56  bin_gege  阅读(119)  评论(0编辑  收藏  举报