BNUOJ 5629 胜利大逃亡(续)

胜利大逃亡(续)

Time Limit: 2000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 1429
64-bit integer IO format: %I64d      Java class name: Main
 
 
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

Source

 
解题:状态压缩搜索。。。。高级搜索?
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define INF 0x3f3f3f3f
15 using namespace std;
16 struct node{
17     int state,step;
18     node(int x = 0,int y = 0):state(x),step(y){}
19 };
20 char mp[30][30];
21 int n,m,t,sx,sy,ex,ey;
22 const int dir[4][2] = {0,-1,0,1,-1,0,1,0};
23 queue<node>q;
24 set<int>s;
25 int compress(int x,int y,int state){
26     int temp = x;
27     temp = (temp<<5)|y;
28     temp = (temp<<10)|state;
29     return temp;
30 }
31 void decompress(int temp,int &x,int &y,int &state){
32     int t = (1<<10)-1;
33     state = temp&t;
34     temp >>= 10;
35     t = (1<<5)-1;
36     y = temp&t;
37     temp >>= 5;
38     x = temp&t;
39 }
40 void addkey(int &state,int t){
41     state |= (1<<t);
42 }
43 int haskey(int state,int t){
44     return state&(1<<t);
45 }
46 int bfs(){
47     while(!q.empty()) q.pop();
48     s.clear();
49     int i,j,x,y,tx,ty,tmpstate,tmp;
50     tmp = compress(sx,sy,0);
51     node temp2 = node(tmp,0);
52     q.push(temp2);
53     s.insert(tmp);
54     while(!q.empty()){
55         node temp2 = q.front();
56         q.pop();
57         if(temp2.step > t) return INF;//必须要的优化
58         for(i = 0; i < 4; i++){
59             decompress(temp2.state,x,y,tmpstate);
60             if(x == ex && y == ey) return temp2.step;
61             tx = x+dir[i][0];
62             ty = y+dir[i][1];
63             if(mp[tx][ty] == '*') continue;
64             if(mp[tx][ty] >= 'a' && mp[tx][ty] <= 'j'){
65                 addkey(tmpstate,mp[tx][ty]-'a');
66             }else if(mp[tx][ty] >= 'A' && mp[tx][ty] <= 'J'){
67                 if(!haskey(tmpstate,mp[tx][ty]-'A')) continue;
68             }
69             tmp = compress(tx,ty,tmpstate);
70             if(s.count(tmp)) continue;
71             s.insert(tmp);
72             q.push(node(tmp,temp2.step+1));
73         }
74     }
75     return INF;
76 }
77 int main(){
78     while(~scanf("%d %d %d",&n,&m,&t)){
79         memset(mp,'*',sizeof(mp));
80         getchar();
81         for(int i = 1; i <= n; i++){
82             for(int j = 1; j <= m; j++){
83                 mp[i][j] = getchar();
84                 if(mp[i][j] == '@') {sx = i;sy = j;}
85                 if(mp[i][j] == '^') {ex = i;ey = j;}
86             }
87             getchar();
88         }
89         int tmp = bfs();
90         printf("%d\n",tmp < t?tmp:-1);
91     }
92     return 0;
93 }
View Code

 

posted @ 2014-08-14 11:35  狂徒归来  阅读(178)  评论(0编辑  收藏  举报