hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

胜利大逃亡(续)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6070    Accepted Submission(s): 2096

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
 
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #include<math.h>
  5 typedef long long ll ;
  6 const int M = 20 + 4 , mod = 1700003 , bas = 29 ;
  7 char map[M][M] ;
  8 int a[M][M][2500  + 10] ;
  9 int move[][2] = {{1,0} , {-1,0} , {0,1} , {0,-1}} ;
 10 int n , m , t ;
 11 struct node
 12 {
 13     int x , y , step ;
 14     int key ;
 15 };
 16 
 17 int bfs (int sx , int sy , int ex , int ey)
 18 {
 19   //  puts ("heheda") ;
 20     std::queue<node> q ;
 21     while (!q.empty ()) q.pop () ;
 22     node ans , tmp ;
 23     q.push ((node) {sx , sy , 0,0}) ;
 24     a[sx][sy][0] = 1 ;
 25     while (!q.empty ()) {
 26         ans = q.front () ; q.pop () ;
 27     //    puts ("He") ;
 28        // printf ("s----------(%d,%d),%d
" , (ans.x , ans.y) , ans.step) ;
 29           if (ans.step >= t) return  -1 ;
 30         if (ans.x == ex &&ans.y == ey ) return a[ans.x][ans.y][ans.key];
 31         for (int i = 0 ; i < 4 ; i ++) {
 32             tmp.x = ans.x + move[i][0] ; tmp.y = ans.y + move[i][1] ;
 33             if (tmp.x < 0 || tmp.y < 0 || tmp.x >= n || tmp.y >= m) continue ;
 34             if (map[tmp.x][tmp.y] == '*') continue ;
 35             char door = map[tmp.x][tmp.y] ;
 36             if (door >= 'A' && door <= 'J' ) if ( ! (ans.key & (int)pow(2,door - 'A') ) ) continue ;
 37             tmp.step = ans.step + 1 ;
 38             tmp.key = ans.key ;
 39             if (door >= 'a' && door <= 'j' ) tmp.key = tmp.key | ((int) pow (2 , door - 'a')) ;
 40             if (a[tmp.x][tmp.y][tmp.key] != - 1 ) continue ;
 41             a[tmp.x][tmp.y][tmp.key] = tmp.step ;
 42             q.push (tmp) ;
 43         }
 44     }
 45     return -1 ;
 46 }
 47 
 48 int main ()
 49 {
 50     //freopen ("a.txt" , "r" , stdin );
 51     while (scanf ("%d%d%d" , &n , &m , &t) == 3) {
 52         int x , y , ex , ey ;
 53        // printf ("n=%d,m=%d,t=%d
" , n , m , t ) ;
 54         memset (a , - 1 , sizeof(a)) ;
 55         for (int i = 0 ; i < n ; i ++) scanf ("%s" , map[i]) ;
 56         for (int i = 0 ; i < n ; i ++) {
 57             for (int j = 0 ; j < m ; j ++) {
 58                 if (map[i][j] == '@') {x = i , y = j ;}
 59                 else if (map[i][j] == '^') {ex = i , ey = j ;} ;
 60             }
 61         }
 62         printf ("%d
" , bfs (x  , y , ex , ey)  ) ;
 63     }
 64     return 0 ;
 65 }
 66 /*
 67 #include<stdio.h>
 68 #include<string.h>
 69 #include<queue>
 70 typedef long long ll ;
 71 const int M = 20 + 4 , mod = 1700003 , bas = 29 ;
 72 char map[M][M] ;
 73 int move[][2] = {{1,0} , {-1,0} , {0,1} , {0,-1}} ;
 74 int n , m , t ;
 75 struct node
 76 {
 77     int x , y , step ;
 78     bool key[30] ;
 79 };
 80 struct hash
 81 {
 82     int w , nxt ;
 83     int x , y , key ;
 84 }e[mod];
 85 int E = 0 , H[mod];
 86 
 87 void insert (int x)
 88 {
 89     int y = x % mod ;
 90     if (y < 0) y += mod ;
 91     e[++ E].w = x ;
 92     e[E].nxt = H[y] ;
 93     H[y] = E ;
 94 }
 95 
 96 bool find (int x , node tmp )
 97 {
 98     int y = x % mod ;
 99     if (y < 0) y += mod ;
100     for (int i = H[y] ; i ; i = e[i].nxt) {
101         if (e[i].w == x) {
102             if (e[i].x == tmp.x && e[i].y == tmp.y && e[i].key)
103         }
104     }
105     return false ;
106 }
107 
108 int bfs (int sx , int sy , int ex , int ey)
109 {
110     std::queue<node> q ;
111     while (!q.empty ()) q.pop () ;
112     node ans , tmp ;
113     q.push ((node) {sx , sy , 0}) ;
114     while (!q.empty ()) {
115         ans = q.front () ; q.pop () ;
116         if (ans.step >= t) return -1 ;
117         if (ans.x == ex && ans.y == ey ) return ans.step ;
118         for (int i = 0 ; i < 4 ; i ++) {
119             tmp.x = ans.x + move[i][0] ; tmp.y = ans.y + move[i][1] ;
120             if (tmp.x < 0 || tmp.y < 0 || tmp.x >= n || tmp.y >= m) continue ;
121             if (map[tmp.x][tmp.y] == '*') continue ;
122             char door = map[tmp.x][tmp.y] ;
123             if (door >= 'A' && door <= 'J' && ans.key[door - 'A' ] == 0) continue ;
124             for (int j = 0 ; j < 26 ; j ++) {
125                 tmp.key[j] = ans.key[j] ;
126             }
127             tmp.step = ans.step + 1 ;
128             if (door >= 'a' && door <= 'j') tmp.key[door - 'a' ] = 1 ;
129             ll rhs = 1 , fac = 1;
130             rhs = (1ll*rhs*fac + tmp.x) % mod ; fac *= 1ll*bas ; rhs = (1ll*rhs*fac+tmp.y) % mod ; fac *= 1ll*bas ;
131             for (int i = 0 ; i < 26 ; i ++) {
132                 if (tmp.key[i]) {
133                     rhs = (1ll*rhs*fac + i * i *i + i *i) % mod ;
134                     fac *= 1ll * bas ;
135                 }
136             }
137             if (find (rhs , tmp)) continue ;
138             insert (rhs , tmp) ;
139             q.push (tmp) ;
140         }
141     }
142     return -1 ;
143 }
144 
145 int main ()
146 {
147   //  freopen ("a.txt" , "r" , stdin );
148     while (~ scanf ("%d%d%d" , &n , &m , &t) ) {
149         int x , y , ex , ey ;
150         for (int i = 0 ; i < n ; i ++) scanf ("%s" , map[i]) ;
151         for (int i = 0 ; i < n ; i ++) {
152             for (int j = 0 ; j < m ; j ++) {
153                 if (map[i][j] == '@') {x = i , y = j ;}
154                 else if (map[i][j] == '^') {ex = i , ey = j ;} ;
155             }
156         }
157         E = 0 ;
158         memset (H, 0 , sizeof(H)) ;
159        printf ("%d
" , bfs (x  , y , ex , ey)  ) ;
160     }
161     return 0 ;
162 }
163 */
View Code

一开始把x , y , key,当做hash的元素,得到一个hash值。
一直wa,后来杰神说,要更加精确的hash值,就是多加点辅助值。

so明白了,不过果然变得很麻烦,给过还是。。。。。

附上用二进制保存钥匙状态的程序。

原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4453486.html