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
     
    解题思路:
      承接 HDU 1253 -  胜利大逃亡 的模板(虽然我感觉改的挺多的)http://www.cnblogs.com/nicetomeetu/p/5156336.html
      依旧用 BFS 走迷宫,钥匙用 状态压缩 来解决;
      在每一步上附上 钥匙状态 ,就解决了门的问题
      将原先图的 flag[x][y] 改为 flag[x][y][key],根据 钥匙状态 的更新解决了原路返回的问题
     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 using namespace std;
     5 struct pr{
     6     int x,y,t,key;//横纵轴,时间,钥匙 
     7 };
     8 const int x[10]={0,0,0,1,-1},y[10]={0,1,-1,0,0};
     9 int a,b,t,sx,sy;
    10 char map[25][25];//输入图 
    11 int flag[25][25][(1<<11)];
    12 queue<pr> s;
    13 pr q,temp;
    14 
    15 bool check(int x,int y){
    16     return x>0&&x<=a&&y>0&&y<=b&&map[x][y]!='*';
    17 }
    18 
    19 bool door(int x,int y,int key){
    20     if(map[x][y]>='A'&&map[x][y]<='Z')
    21          return (1<<(map[x][y]-'A'+1))&key;
    22      return 1;
    23 }
    24 
    25 void bfs(){
    26     int i,j,k;
    27     while(!s.empty()) 
    28     s.pop();
    29     memset(flag,0,sizeof(flag)); 
    30     flag[sx][sy][0]=1;
    31     q.x=sx; q.y=sy; q.t=0; q.key=0;
    32     s.push(q);
    33     while(!s.empty())
    34     {
    35         q=s.front();
    36         s.pop(); 
    37         if(q.t>=t){//被抓 
    38             cout<<-1<<endl; return ;
    39         }
    40         if(map[q.x][q.y]=='^'){//找到出口 
    41             cout<<q.t<<endl;
    42             return;
    43         }
    44         for(i=1;i<=4;i++){
    45             int nx=q.x+x[i];
    46             int    ny=q.y+y[i];
    47             int newkey=q.key;
    48             if(check(nx,ny)&&door(nx,ny,newkey)){
    49                 if(!flag[nx][ny][newkey]){
    50                     flag[nx][ny][newkey]=1;
    51                     if(map[nx][ny]>='a'&&map[nx][ny]<='z')//更新钥匙 
    52                         newkey=(1<<(map[nx][ny]-'A'+1)|q.key);
    53                     flag[nx][ny][newkey]=1;
    54                     temp.x=q.x+x[i];
    55                     temp.y=q.y+y[i];
    56                       temp.t=q.t+1;
    57                     temp.key=newkey;
    58                     s.push(temp);
    59                 }
    60             }
    61         }
    62     }
    63     cout<<-1<<endl;
    64 }
    65 int main()
    66 {
    67     int i,j;
    68     for(;cin>>a>>b>>t;)
    69     {
    70         for(i=1;i<=a;i++)
    71             for(j=1;j<=b;j++){
    72                 cin>>map[i][j];
    73                 if(map[i][j]=='@')
    74                 {
    75                     sx=i;
    76                     sy=j;
    77                 }
    78             }
    79         bfs();
    80     } return 0;
    81 }
    我自倾杯,君且随意
  • 相关阅读:
    科大奥瑞大物实验-A类不确定度计算器 代码
    在手机和电脑间双向加密传输文件 —— Windows 安装 Kde Connect
    Leetcode 寻找两个有序数组的中位数
    树莓派3B安装 Arch Linux ARM
    从零开始编译安装 Extcalc
    Oracle, PostgreSQl, MySQL针对INSERT时可能唯一键重复的SQL
    如何从Oracle, MySql, PostgreSQL的PreparedStatement获得所执行的sql语句?
    PostgreSQL报错:当前事务被终止,命令被忽略,直到事务块结束
    PostgreSQL对GROUP BY子句使用常量的特殊限制
    一种用JDBC实现批量查询的巧妙方法
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5156471.html
Copyright © 2011-2022 走看看