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 }
  • 相关阅读:
    HTML语义化之常见模块
    取当前时间,格式为,yyyy-mm-dd hh:mm:ss
    利用JS 在网页上获取并显示当前日期 星期
    Javascript Math ceil()、floor()、round()三个函数的区别
    JS,JQUERY 常用笔记
    适配不同分辨率屏幕
    选取节点常用方法
    js控制使div自动适应居中
    点击jQuery Mobile的按钮改变颜色
    左侧固定宽度 右侧自适应
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4730422.html
Copyright © 2011-2022 走看看