题目链接:https://vjudge.net/contest/84620#problem/K

题目大意:一个人从起点走到终点,问他是否能够在规定的时间走到,在走向终点的路线上,可能会有一些障碍门,他需要在路上捡到开门的对应钥匙,才能通过这扇门。如果他到达终点的时间超过了规定时间,或者他根本就走不到终点,输出-1,否则的话,输出他走的步数。

解题思路:此题与普通的bfs类似,只不过到下一个点的时候,要加上一些判断,如果是钥匙,则将它储存起来,如果是门,则判断是否已经捡到了对应的钥匙,如果有对应钥匙,则这个门与其它 '.' 无异,如果没有对应的钥匙,则不能通过。这个功能是由状态压缩来实现的,将钥匙的对应序号转化成二进制,方便钥匙的存储和判断。另外,还有一个需要注意的就是vis数组的设置,此题只要仔细思考就会发现,设置成二维的显然不行,因为走过的路是可以重复走的,只不过你钥匙的数量要增加,比如说,你走到了一扇门那里,但是你没有钥匙,你只好向别的方向继续搜索,当你捡到对应的钥匙后,可以沿着原路返回到那扇门那里。因此,为了满足题目意思,又不需要走太多重复的路,这样的设置还是挺合理的。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int vis[][][]; <<=
char map[][];
int dir[][] = {,,,,-,,,-};
int n, m,t; struct node
{
int x;
int y;
int key;
int step;
}; queue<node>q; int bfs()
{
node s,now, next;
int i, j,nx,ny;
while (!q.empty())
{
now = q.front();
q.pop();
if (map[now.x][now.y] == '^')
{
/*now.step < t ?printf("%d\n", now.step) : printf("-1\n"); */ //不能这样写,因为它可能走不到终点
if (now.step < t)return now.step;
}
for (i = ; i < ; i++)
{
nx = now.x + dir[i][];
ny = now.y + dir[i][];
if (nx < || nx >= n || ny < || ny >= m || map[nx][ny] == '*')continue;
else if ((map[nx][ny] == '.'||map[nx][ny]=='^') && !vis[nx][ny][now.key])
{
vis[nx][ny][now.key] = ;
next.x = nx, next.y = ny;
next.step = now.step + , next.key = now.key;
q.push(next);
}
else if (map[nx][ny] >= 'A'&&map[nx][ny] <= 'J'&&vis[nx][ny][now.key] == )
{
int key = << (map[nx][ny] - 'A');
if (now.key&key)
{
vis[nx][ny][now.key] = ;
next.x = nx, next.y = ny;
next.step = now.step + ;
next.key = now.key;
q.push(next);
}
}
else if (map[nx][ny] >= 'a'&&map[nx][ny] <= 'j' && !vis[nx][ny][now.key])
{
int key = << (map[nx][ny] -'a');
vis[nx][ny][now.key] = ;
next.x = nx, next.y = ny;
next.step = now.step + ;
next.key = now.key | key;
q.push(next);
}
}
}
return -;
} int main()
{
int i, j;
node s;
while (scanf("%d%d%d", &n, &m, &t) != EOF)
{
while (!q.empty())q.pop();
memset(vis, , sizeof(vis));
for (i = ; i < n; i++)
{
scanf("%s", &map[i]);
for (j = ; j < m; j++)
{
if (map[i][j] == '@')
{
s.x = i;
s.y = j;
map[i][j] = '.';
}
}
}
s.key = ; s.step = ;
vis[s.x][s.y][s.key] = ;
q.push(s);
printf("%d\n", bfs());
}
return ;
}
2018-03-26

hdu1429 胜利大逃亡(续) 【BFS】+【状态压缩】的更多相关文章

  1. HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...

  2. hdu - 1429 胜利大逃亡(续) (bfs状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=1429 终于开始能够做状态压缩的题了,虽然这只是状态压缩里面一道很简单的题. 状态压缩就是用二进制的思想来表示状态 ...

  3. hdu 1429 胜利大逃亡(续) (bfs+状态压缩)

    又开始刷题了 题意:略过. 分析:主要是确定状态量,除了坐标(x,y)之外,还有一个key状态,就好比手上拿着一串钥匙.状态可以用位运算来表示:key&(x,y)表示判断有没有这扇门的钥匙,k ...

  4. 胜利大逃亡(续)(状态压缩bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. hdu 1429 胜利大逃亡(续)(bfs+位压缩)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  6. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. Hdu1429 胜利大逃亡(续) 2017-01-20 18:33 53人阅读 评论(0) 收藏

    胜利大逃亡(续) Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Subm ...

  8. hdu_1429_胜利大逃亡(续)(BFS状压)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 题意:迷宫的加强版,迷宫里有钥匙和门,问在指定的时间下能否逃出 题解:用二进制位来记录是否有该门 ...

  9. 胜利大逃亡(续)(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1429 #include <stdio.h> #include <queue> #incl ...

随机推荐

  1. Confluence 6 MBeans

    你可以使用下面的 Confluence MBeans  来实时查看你 Confluence 实例运行的实时信息. CacheStatistics 这个 MBean 显示了 Confluence 有关的 ...

  2. Confluence 6 自定义默认空间内容

    中文标题[自定义默认空间内容] Confluence 管理员 可以编辑用于创建主页和新站点的模板.默认的内容将会在新空间创建后的主页上显示出来.这个与站点空间,个人空间和空间蓝图的模板是不同的. 模板 ...

  3. Spark SQL访问PostgreSQL

    随着Spark SQL的正式发布,以及它对DataFrame的支持,它可能会取代HIVE成为越来越重要的针对结构型数据进行分析的平台.在博客文章What’s new for Spark SQL in ...

  4. 量化投资与Python

    目录: 一.量化投资第三方相关模块 NumPy:数组批量计算 Pandas:表计算与数据分析 Matplotlib:图表绘制 二.IPython的介绍 IPython:和Python一样 三.如何使用 ...

  5. tp3.2 事务

    public function exchangeTransfer($user_id, $type, $money, $config, $other_id = 0) { $r['code'] = ERR ...

  6. Advanced Wlan Attacks (RADIUS)

    1.查询连接到无线接入点的情况 使用命令 airodump-ng  wlan0mon  可以看到 有用的信息.我们知道如果有一个客户端使用验证码成功连接到. 顺便查一下其中一个连接的设备的MAC地址的 ...

  7. Linux系统下inode满了导致无法写文件的解决思路

    解决思路1:删除无用的临时文件,释放inode 进入/tmp目录,执行find -exec命令 find  /tmp  -type  f  -exec  rm  {}  \; 遍历寻找0字节的文件,并 ...

  8. web和servlet一样的用法但是有区别

  9. 【C++ Primer | 15】访问控制与继承、继承中的类作用域

    1. 只有D继承B的方式是public时,用户代码才能使用派生类向基类的转换:如果D继承B的方式是受保护的或者私有的,则用户代码不能使用该转换. 2. 不论D以什么方式继承B,D的成员函数和友员函数都 ...

  10. Personal小金库(避免遗忘,优秀的网址会保存于此方便自己查看)

    由于记性不好,~.~,所以整理了一下一些自己经常看的网址或者博客......不断更新中,如果对您造成了侵权,我立马删除.谢谢~.~ 1:个人的一些link~.~ 博客园名称:别先生 博客园网址:htt ...