• 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明白了,不过果然变得很麻烦,给过还是。。。。。

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

  • 相关阅读:
    【转】滑动窗口与拥塞控制
    LeetCode 34 :Find First and Last Position of Element in Sorted Array
    主要电商模式介绍
    使用springboot创建邮件服务器
    解决Windows下端口占用问题
    [leetcode]给定二维平面上的n个点,找出位于同一直线上的点的最大数目
    获得超类的泛型参数在子类实例化传入的实际类型
    构造单例的五种方法
    20162308 2017-2018-2 《程序设计与数据结构》第11周学习总结
    20162308 2017-2018-2 《程序设计与数据结构》第十周学习总结
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4453486.html
Copyright © 2020-2023  润新知