zoukankan      html  css  js  c++  java
  • 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
    ",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
    ");
    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 }
  • 相关阅读:
    Python python __def__ Exception AttributeError: "'NoneType' object has no attribute
    Python sys.argv[]用法
    Python 编写通过DOS压缩的例子遇到的几个问题
    DOS rar压缩
    Oracle游标介绍
    C#保存日志文件到txt中,可追加保存,定时删除最后一次操作半年前日志文件
    VS2008生成解决方案卡顿、龟速
    VS工具箱中添加DevExpress控件
    CLR 无法从 COM 上下文 0x208f68 转换为 COM 上下文 0x2090d8,这种状态已持续 60 秒
    命名空间"xx"已经包含了"xx"的定义
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4730422.html
Copyright © 2011-2022 走看看