HDU-1429 胜利大逃亡(续) (BFS+状态压缩)

Problem Description
Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
 
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:

. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J

每组测试数据之间有一个空行。
 
Output
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。
 
Sample Input
4 5 17
@A.B.
a*.*.
*..*^
c..b*
4 5 16
@A.B.
a*.*.
*..*^
c..b*
 
Sample Output
16
-1
 
题目大意:在迷宫中,有一些门锁着,每个门对应一把钥匙,只有拥有门的钥匙才能经过该门。要求在规定的时间内走出迷宫。注意:门不是迷宫的出口。
题目分析:主要问题就是状态表示。总共钥匙数不超过10把,容易想到状态压缩。当遇到一把新钥匙时,通过“|”运算来改变状态,当遇到门时,用“&”运算来判断是否已经拥有该门的钥匙。
 
代码如下:
 1 # include<iostream>
 2 # include<cstdio>
 3 # include<queue>
 4 # include<cstring>
 5 # include<algorithm>
 6 using namespace std;
 7 int vis[25][25][1050];
 8 char p[25][25];
 9 int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
10 struct node
11 {
12     int x,y,t,s;
13     node(int a,int b,int c,int d):x(a),y(b),t(c),s(d){}
14 };
15 void bfs(int sx,int sy,int n,int m,int T)
16 {
17     memset(vis,0,sizeof(vis));
18     queue<node>q;
19     vis[sx][sy][0]=1;
20     q.push(node(sx,sy,0,0));
21     int cnt=0;
22     while(!q.empty())
23     {
24         node u=q.front();
25         q.pop();
26         if(u.t>=T)
27             continue;
28         int x=u.x,y=u.y;
29         if(p[x][y]=='^'){
30             printf("%d\n",u.t);
31             return ;
32         }
33         for(int i=0;i<4;++i){
34             int nx=x+d[i][0],ny=y+d[i][1];
35             if(nx<0||nx>=n||ny<0||ny>=m)
36                 continue;
37             if(p[nx][ny]=='*')
38                 continue;
39             int s=u.s;
40             if(p[nx][ny]>='A'&&p[nx][ny]<='J'&&!(s&(1<<p[nx][ny]-'A')))
41                    continue;
42             if(p[nx][ny]>='a'&&p[nx][ny]<='j')
43                 s=s|(1<<(p[nx][ny]-'a'));
44             if(vis[nx][ny][s])
45                 continue;
46             vis[nx][ny][s]=1;
47             q.push(node(nx,ny,u.t+1,s));
48         }
49     }
50     printf("-1\n");
51 }
52 int main()
53 {
54     int n,m,t,sx,sy;
55     while(scanf("%d%d%d",&n,&m,&t)!=EOF)
56     {
57         int cnt=0;
58         for(int i=0;i<n;++i){
59             scanf("%s",p[i]);
60             for(int j=0;j<m;++j){
61                 if(p[i][j]=='@')
62                     sx=i,sy=j;
63             }
64         }
65         bfs(sx,sy,n,m,t);
66     }
67     return 0;
68 }

 

posted @ 2015-08-14 16:35  20143605  阅读(446)  评论(0编辑  收藏  举报