程序设计与算法MOOC021:鸣人与佐助(C++DFS、剪枝)
题目要求
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
样例输入1
4 4 1
#@##
**##
###+
****样例输入2
4 4 2
#@##
**##
###+
****
输出
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。
样例输出1
6样例输出2
4
题目分析
这道题在DFS时把查克拉T作为一个参数会更加方便,然后把#和*分开来判断,遍历上下左右四种走法,DFS走完后记得回溯,也就是把访问置为未访问、加上的时间减回去。
此外,这道题需要剪枝操作,否则会超时。跟老师讲的一样,使用两个最优性剪枝:
1.走到这一步的时间已经超过了目前记录的最短时间,自然也就没必要走下去了,return。
2.记录走到每个点时,花费的不同查克拉情况下的时间。如果花费查克拉相等时,现在比以前花的时间长,那也没必要走下去了,return。
记得在DFS里包含起点@的情况,否则无法进入递归循环。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int M, N, T;
int flag = 0; //标记是否走到了终点
int mintime;
int totaltime;
char all[210][210]; //原始数组
int visited[210][210]; //标记是否访问过
int minl[210][210][11]; //minl[m][n][t] 表示走到m,n这个点时还有t查克拉情况下的最小时间
void dfs(int m, int n, int t)
{if (all[m][n] == '+') {mintime = min(mintime, totaltime);flag = 1;return;}if (visited[m][n] || m < 0 || n < 0 || m >= M || n >= N)return;else if (!visited[m][n] && all[m][n] == '#' && t > 0) {if (totaltime+1 >= mintime)return;if (totaltime+1 >= minl[m][n][t])return;++totaltime;minl[m][n][t] = totaltime;visited[m][n] = 1;dfs(m - 1, n, t - 1);dfs(m + 1, n, t - 1);dfs(m, n - 1, t - 1);dfs(m, n + 1, t - 1);--totaltime;visited[m][n] = 0;}else if (!visited[m][n] && all[m][n] == '*' || all[m][n]=='@') {if (totaltime+1 >= mintime)return;if (totaltime+1 >= minl[m][n][t])return;++totaltime;minl[m][n][t] = totaltime;visited[m][n] = 1;dfs(m - 1, n, t);dfs(m + 1, n, t);dfs(m, n - 1, t);dfs(m, n + 1, t);--totaltime;visited[m][n] = 0;}
}
int main()
{while (cin >> M >> N >> T) {int mi, ni; //记录起点位置for (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {cin >> all[i][j];if (all[i][j] == '@') {mi = i; ni = j;}}}totaltime = 0;mintime = 0x3f3f3f3f;memset(visited, 0, sizeof(visited));memset(minl, 0x3f3f3f3f, sizeof(minl));dfs(mi, ni, T);if (flag == 1)cout << mintime;elsecout << -1;}return 0;
}
程序设计与算法MOOC021:鸣人与佐助(C++DFS、剪枝)相关推荐
- 百练6044--鸣人与佐助(BFS)
题目大意:又是迷宫啊迷宫啊.鸣人救佐助,一开始手上有一定数量的查克拉,路上遇见大蛇丸的手下,需要耗费一个查克拉杀死对方,才能继续走,然而鸣人能够瞬杀,不耗费时间,只消耗移动距离的时间.没有查克拉,就要 ...
- NOI / 2.5基本算法之搜索-6044:鸣人和佐助详解
总时间限制: 1000ms 内存限制: 65536kB 题目 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到, ...
- 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?
题目: 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下 ...
- 算法基础:4115:鸣人和佐助--广度优先搜索
题目: 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下 ...
- 机器人鸣人是哪一集_博人传:佐良娜因爱开启二勾玉!迪帕是机器人,大蛇丸很怕鸣人?...
在<博人传>动画最新剧情中,围绕着壳组织的外阵成员迪帕和维克托的故事告一段落,看完这个结局后大家才会发现,其实迪帕和维克托并没有那么强,这也是为什么鸣人和佐助都没来而只是让大蛇丸来收尾,毕 ...
- 第9周测验-鸣人和佐助
021:鸣人和佐助 1. 题目详情 描述 输入 输出 样例输入 样例输出 2.思路分析 2.1 整体思路 2.2 限制条件处理 2.3 剪枝 3.注意点 4.AC代码 5.总结 1. 题目详情 描述 ...
- 计蒜客题解——T1214:鸣人和佐助
题目相关 题目链接 计蒜客 OJ,https://nanti.jisuanke.com/t/T1214. 题目描述 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到 ...
- OpenJ_Bailian——4115鸣人和佐助(带状态的A*)
鸣人和佐助 Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit Status Desc ...
- Bailian4115 鸣人和佐助【BFS】
4115:鸣人和佐助 总时间限制: 1000ms 内存限制: 65536kB 描述 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上 ...
最新文章
- Day12 Java异常处理与程序调试
- 汇编:内存地址为什么从0开始?等问题
- 《java编程思想》学习笔记——复用类
- Android五:Activity
- 【文章】七不出,八不归,原来是这个意思
- 【环境搭建000】详细图解ubuntu 上安装配置eclips
- 特斯拉CEO马斯克:可能明年3月左右在中国推出Model S Plaid
- python 命令模式_python 设计模式之命令模式
- sql统计表中各类型金额_产品经理市场需求旺盛的10大基础技能——第1篇读透SQL...
- Elastic 技术栈之 Filebeat
- java 200以内质数_Java:2-200内的质数
- c语言自定义结构,C语言如何定义结构体
- python k线斜率计算_python求线性回归斜率
- 73个必会的经济类热词
- [Js] Js实现继承的5种方式
- 蓝桥杯基础-【切面条】不用画图的解题思路
- sshpass命令的安装使用
- springmvc 升级到5.2.15版本,前台时间显示时间戳全局处理
- ehcache 缓存丢失_求助,EhCache缓存中数据失效的问题!
- H7-TooL高速 DAPLINK仿真器,含全功能版 RTT Viewer