计蒜客题解——T1214:鸣人和佐助
题目相关
题目链接
计蒜客 OJ,https://nanti.jisuanke.com/t/T1214。
题目描述
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费 1 个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入格式
输入的第一行包含三个整数:M,N,T。代表 M 行 N 列的地图和鸣人初始的查克拉数量 T。0<M,N<200,0≤T<10
后面是 M 行 N 列的地图,其中 @ 代表鸣人,+ 代表佐助。* 代表通路,# 代表大蛇丸的手下。
输出格式
输出包含一个整数 R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出 −1。
样例输入1
4 4 1
#@##
**##
###+
****
样例输出1
6
样例输入2
4 4 2
#@##
**##
###+
****
样例输出2
4
题目分析
题意分析
一个 M*N 大小的迷宫,我们从 @ 位置出发(也就是起点),字符 * 表示可以安全通行的方格,字符 # 表示有怪物(可以杀死,但是需要付出代价),字符 * 表示仙药(也就是终点)。要求输出从 @ 到 * 的最短路径。那么迷宫问题的基本要素全齐了,所以本题就是一道 BFS 模板题。
和上一题,https://blog.csdn.net/justidle/article/details/104662118,最大的不同是在于:杀死大蛇丸的手下是需要付出代价的,也就是所谓的查克拉。而题目提供的查克拉是有限的。因此本题最大的变化就是如何表示查克拉的变化。
对于 # 表示的地点,我们有两种操作。第一种,查克拉够,我们可以杀死大蛇丸的手下,通过这个地方。第二种查克拉不够,那么意味着这里不能通过,需要绕道。如何表示查克拉,是本题最大的变化。因为某个位置导致查克拉变化后,其后所有状态都会发生改变。所以我们将 visit 数组从二维变为三维,也就是最后一维表示不同查克拉状态的访问性。
样例数据分析
如果想看类似的数据分析,可以看以前的文章,https://blog.csdn.net/justidle/article/details/104651311。主要是我偷懒了,画图太累了,请原谅。
算法思路
1、读入数据,并写入到合适的数据结构中。
2、找到起点位置,将起点加入到队列 q 中。
3、记录终点位置信息。
4、开始 BFS 遍历。直到找到终点或者遍历所有节点而无法到达终点。碰到 # 的道路,需要判断查克拉。
AC 参考代码
#include <cstdio>
#include <queue>struct POS {int x, y;//坐标int t;//查克拉数int dis;//距离
};const int MAXN = 202;
const int MAXT = 10;
struct MAZE {int row, col;int t;char data[MAXN][MAXN];//迷宫数据 bool visit[MAXN][MAXN][MAXT];//访问性 int x1, y1;int x2, y2;
};int bfs(MAZE &maze);int main() {MAZE maze = {};//迷宫定义//读入迷宫长宽 scanf("%d %d %d", &maze.row, &maze.col, &maze.t);//读入迷宫数据int i,j;for (i=0; i<maze.row; i++) {for (j=0; j<maze.col; j++) {scanf(" %c", &maze.data[i][j]);if (maze.data[i][j]=='+') {//终点maze.x2 = i;maze.y2 = j; } else if (maze.data[i][j]=='@') {//起点maze.x1 = i;maze.y1 = j; }}} int ans = bfs(maze);printf("%d\n", ans);return 0;
}int bfs(MAZE &maze) {std::queue<POS> q;const POS move[] = {{-1,0}, {0,1}, {1,0}, {0,-1}};POS cur, next;//加入起点cur.x = maze.x1;cur.y = maze.y1;cur.dis = 0;cur.t = maze.t;q.push(cur); maze.visit[cur.x][cur.y][cur.t] = true;//开始遍历while (!q.empty()) {cur = q.front();q.pop();for (int i=0; i<4; i++) {next.x = cur.x + move[i].x;next.y = cur.y + move[i].y;//判断是不是终点if (next.x==maze.x2 && next.y==maze.y2) {return cur.dis+1;} //判断通过性if (next.x>=0&&next.x<maze.row&&next.y>=0&&next.y<maze.col) {if (maze.data[next.x][next.y]!='#') {//通路或者佐助 if (maze.visit[next.x][next.y][cur.t]==false) {next.t = cur.t;next.dis = cur.dis + 1;q.push(next);maze.visit[next.x][next.y][next.t] = true;}} else {//大蛇丸的手下if (cur.t > 0 && maze.visit[next.x][next.y][cur.t-1]==false) {next.t = cur.t - 1;next.dis = cur.dis + 1;q.push(next);maze.visit[next.x][next.y][next.t] = true;} }}}}return -1;
}
代码分析
1、由于有查克拉的存在,每个结点需要增加查克拉信息记录。代码部分如下:
struct POS {int x, y;//坐标int t;//查克拉数int dis;//距离
};
2、关于 # 的处理。注意代码中对通过性的判断。以前题目中,我们是将本节点能否走和其他条件一起判断。这里,我们需要分开判断,先判断其他条件,再判断是否为大蛇丸的手下(即 #)。代码部分如下:
if (maze.data[next.x][next.y]!='#') {不是大蛇丸的手下,那么操作和以前一样
} else {大蛇丸手下先判断查克拉是否够用 cur.t>0再判断查克拉减 1 后是否访问过 maze.visit[next.x][next.y][cur.t-1]==false
}
计蒜客题解——T1214:鸣人和佐助相关推荐
- T1214 鸣人和佐助——dfs、bfs
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 分析 bfs 迷宫问题,求最短时间,和 拯救行动 差不多,存在打怪兽可以通过的另外条件:但是此题打怪兽不需要另耗时间,所以第一次找到的终点就是最短时 ...
- OpenJudge-021:鸣人和佐助
OpenJudge-021:鸣人和佐助 题目描述: 题目传送门:添加链接描述 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要 ...
- OpenJ_Bailian——4115鸣人和佐助(带状态的A*)
鸣人和佐助 Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit Status Desc ...
- Bailian4115 鸣人和佐助【BFS】
4115:鸣人和佐助 总时间限制: 1000ms 内存限制: 65536kB 描述 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上 ...
- 第9周测验-鸣人和佐助
021:鸣人和佐助 1. 题目详情 描述 输入 输出 样例输入 样例输出 2.思路分析 2.1 整体思路 2.2 限制条件处理 2.3 剪枝 3.注意点 4.AC代码 5.总结 1. 题目详情 描述 ...
- O - 鸣人和佐助(BFS)
O - 鸣人和佐助 题目 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要 ...
- 计蒜客题解——T1414:抠图
题目相关 题目链接 计蒜客,https://nanti.jisuanke.com/t/T1414. 我的 OJ,http://47.110.135.197/problem.php?id=4768. 题 ...
- 计蒜客题解——T1213:拯救行动
题目相关 题目链接 计蒜客 OJ,https://nanti.jisuanke.com/t/T1213. 题目描述 公主被恶人抓走,被关押在牢房的某个地方.牢房用 N×M(N,M≤200) 的矩阵来表 ...
- 计蒜客题解——T1769:最大岛屿
题目相关 题目链接 计蒜客,https://nanti.jisuanke.com/t/T1405. 我的OJ,http://47.110.135.197/problem.php?id=5254. 题目 ...
最新文章
- MIT无人车新突破:不需要地图也能在“乡野小道”上自动行驶
- 基于Struts 2的自定义类型转换器
- 使用logon trigger完成动态的session跟踪
- 林海峰老师python课件密码
- [Luogu1890]gcd区间
- 学习笔记5-C语言-数组
- java 并发测试main方法_Java并发测试
- 滚轮y坐标html,web交互之js事件
- 与二次元老婆邂逅的游戏的创建过程(二)
- Pspice仿真实验 B-3
- python turtle setheading_Python turtle.right与turtle.setheading的区别
- 如何申请注册在国内可以登录使用国外邮箱?
- 转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧
- 行数据上加一个version版本字段,可以有效防止数据重复更新
- 4399U3D笔试题
- C#:今日上机问题描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。
- Xamarin是无懈可击还是鸡肋?浅谈对Xamarin的学习
- 大佬谈 996, 马云,刘强东,李国庆,人民日报
- 再见SpringMVC!字节跳动正式启动2021届秋季校招!不可思议!
- commons-logging的使用