zoukankan      html  css  js  c++  java
  • HDU_1429——胜利大逃亡续,十位二进制状态压缩,状态判重

    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 <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 using namespace std;
      5 
      6 const int dir[4][2] = {0,1,0,-1,1,0,-1,0};
      7 int n, m, t;
      8 char map[25][25];
      9 
     10 struct node
     11 {
     12     int x, y, key;                //key的每一个二进制位代表一种钥匙
     13     int step;
     14     bool out(void)
     15     {
     16         if(map[x][y] == '^')
     17         {
     18             return true;
     19         }
     20         return false;
     21     }
     22     bool check(void)
     23     {
     24         if(x>=0 && x<n && y>=0 && y<m)
     25         {
     26             if(map[x][y] != '*')
     27             {
     28                 return true;
     29             }
     30         }
     31         return false;
     32     }
     33     bool is_key(void)
     34     {
     35         if(map[x][y]>='a' && map[x][y]<='j')
     36         {
     37             return true;
     38         }
     39         return false;
     40     }
     41     bool is_door(void)
     42     {
     43         if(map[x][y]>='A' && map[x][y]<='J')
     44         {
     45             return true;
     46         }
     47         return false;
     48     }
     49 }u,v;
     50 
     51 //标记已搜索过的状态,根据主角手中拿到的不同的钥匙及其所在位置来区分不同的状态,
     52 //就像推箱子中,用所达某一位置时人物面对的方向来标记某一个状态
     53 int mark[25][25][1024];                //数组太大不能在函数中定义 
     54 int BFS(void)
     55 {
     56     memset(mark,0,sizeof(mark));
     57     queue<node>que;
     58     que.push(u);
     59     
     60     while(!que.empty())
     61     {
     62         u = que.front();
     63         que.pop();
     64         
     65         if(u.out())                            //逃出 
     66         {
     67             return (t - u.step);
     68         }
     69         for(int i=0; i<4; i++)            //枚举方向 
     70         {
     71             v.x = u.x + dir[i][0];
     72             v.y = u.y + dir[i][1];
     73             v.step = u.step - 1;
     74             v.key = u.key;
     75             
     76             if(v.step == 0)                //逃不出 
     77             {
     78                 continue;
     79             }
     80             
     81             if(v.check() && !mark[v.x][v.y][v.key])        //检查越界,撞墙,标记重复 
     82             {
     83                 if(v.is_key())                                        //走到钥匙 
     84                 {
     85                     v.key |= 1 << (map[v.x][v.y] - 'a');    //把钥匙带走,对应二进制标志位置1 
     86                 }
     87                 else if(v.is_door())                                //走到门 
     88                 {
     89                     if((v.key & (1 << (map[v.x][v.y] - 'A'))) == 0)    //身上的钥匙不能开这个门 
     90                     {
     91                         continue;
     92                     }
     93                 }
     94                 mark[v.x][v.y][v.key] = 1;
     95                 que.push(v);
     96             }
     97         }
     98     }
     99     return -1;
    100 }
    101 
    102 int main()
    103 {
    104     while(~scanf("%d%d%d", &n,&m,&t))
    105     {
    106         for(int i=0; i<n; i++)
    107         {
    108             scanf("%s", map[i]);
    109             for(int j=0; j<m; j++)
    110             {
    111                 if(map[i][j] == '@')
    112                 {
    113                     u.x = i;
    114                     u.y = j;
    115                     u.key = 0;
    116                     u.step = t;
    117                 }
    118             }
    119         }
    120         printf("%d
    ",BFS());
    121     }
    122     return 0;
    123 }
    ——现在的努力是为了小时候吹过的牛B!!
  • 相关阅读:
    OAuth2.0 基础概述
    Ubuntu安装Gogs服务
    ASP.NET WebAPI 生成帮助文档与使用Swagger服务测试
    ASP.NET MVC 中的路由
    升级Ghost
    搭建Golang开发环境
    TDD并不是看上去的那么美
    .NET Framework 源码查看与调试
    在 ASP.NET MVC 中使用异步控制器
    SpringMVC+FreeMarker+Mybatis 整合
  • 原文地址:https://www.cnblogs.com/pingge/p/3215298.html
Copyright © 2011-2022 走看看