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
 #include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int dir[][] = {,,,-,,,-,};
int n, m, t;
char map[][]; struct node
{
int x, y, key; //key的每一个二进制位代表一种钥匙
int step;
bool out(void)
{
if(map[x][y] == '^')
{
return true;
}
return false;
}
bool check(void)
{
if(x>= && x<n && y>= && y<m)
{
if(map[x][y] != '*')
{
return true;
}
}
return false;
}
bool is_key(void)
{
if(map[x][y]>='a' && map[x][y]<='j')
{
return true;
}
return false;
}
bool is_door(void)
{
if(map[x][y]>='A' && map[x][y]<='J')
{
return true;
}
return false;
}
}u,v; //标记已搜索过的状态,根据主角手中拿到的不同的钥匙及其所在位置来区分不同的状态,
//就像推箱子中,用所达某一位置时人物面对的方向来标记某一个状态
int mark[][][]; //数组太大不能在函数中定义
int BFS(void)
{
memset(mark,,sizeof(mark));
queue<node>que;
que.push(u); while(!que.empty())
{
u = que.front();
que.pop(); if(u.out()) //逃出
{
return (t - u.step);
}
for(int i=; i<; i++) //枚举方向
{
v.x = u.x + dir[i][];
v.y = u.y + dir[i][];
v.step = u.step - ;
v.key = u.key; if(v.step == ) //逃不出
{
continue;
} if(v.check() && !mark[v.x][v.y][v.key]) //检查越界,撞墙,标记重复
{
if(v.is_key()) //走到钥匙
{
v.key |= << (map[v.x][v.y] - 'a'); //把钥匙带走,对应二进制标志位置1
}
else if(v.is_door()) //走到门
{
if((v.key & ( << (map[v.x][v.y] - 'A'))) == ) //身上的钥匙不能开这个门
{
continue;
}
}
mark[v.x][v.y][v.key] = ;
que.push(v);
}
}
}
return -;
} int main()
{
while(~scanf("%d%d%d", &n,&m,&t))
{
for(int i=; i<n; i++)
{
scanf("%s", map[i]);
for(int j=; j<m; j++)
{
if(map[i][j] == '@')
{
u.x = i;
u.y = j;
u.key = ;
u.step = t;
}
}
}
printf("%d\n",BFS());
}
return ;
}

最新文章

  1. 八、java集合类
  2. 一个简单且丑陋的js切换背景图片基础示例
  3. C51单片机模拟I2C总线驱动程序设计
  4. VC中判断指定窗口是否被其他窗口遮挡
  5. EF使用时异常:对一个或多个实体的验证失败。有关详细信息
  6. response的contentType 几种类型
  7. C#函数式编程-序列
  8. Keras官方中文文档:Keras安装和配置指南(Linux)
  9. eclipse快速查看工程代码行数
  10. Winsock编程基础2(UDP流程)
  11. LeetCode Weekly Contest 118
  12. mysql中利用show profile很直观的看到查询缓存的作用。
  13. 获取 Google USB 驱动程序
  14. 新玩的windows phone app studio
  15. json格式字符串处理
  16. 网友写的解决uniGUI限制的方法
  17. 《Android源码设计模式》--抽象工厂模式
  18. redis位图
  19. 关于一次美团java程序员招聘面试的经历
  20. [日常] NOIp 2018 滚粗记

热门文章

  1. wpf的学习日志(二)
  2. struts2学生信息管理系统篇章③
  3. window.applicationCache事件,介绍
  4. 一个PHP开发者总结的九条建议
  5. [!] CocoaPods was not able to update the `master` repo...
  6. jQuery之防止冒泡事件,冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件。
  7. javascript基础学习(十二)
  8. 实现textarea限制输入字数
  9. [jQuery编程挑战]001:实现页面元素加速动画效果
  10. 逻辑很重要:一句sql语句的事,自己却想了半天,绕了个大弯子