HNUST 挑战ACM迷宫(DFS)
题目描述
如下图所示的是一个由程序设计题目组成的ACM迷宫。迷宫的左上角是入口,右下角是出口。迷宫中每一个格子都有一个程序设计题目,挑战者要AC该题目后才能通过,大于0的数字表示AC该题目所需的最短时间。数字如果是0表示是陷阱,进去了就出不来。现在的问题是:求挑战者从入口到出口所需的最短时间。输入
有多组测试实例。
对于每组测试实例,先输入一个数字n(1< n <= 100),然后输入n*n个数字表示迷宫中的数字。输出
对应输出挑战者从入口到出口所需的最短时间。样例输入
10
1 0 2 1 2 3 4 2 2 5
2 1 0 1 3 2 5 7 2 1
1 1 1 0 1 1 1 3 2 3
1 2 1 1 0 1 1 1 2 3
1 1 2 0 2 0 2 3 2 3
2 2 2 2 3 2 0 2 3 2
3 2 2 2 1 1 1 0 1 1
0 1 1 3 0 1 1 2 3 2
2 0 1 1 2 2 2 2 2 2
3 2 3 2 3 2 3 2 3 2
5
1 2 1 2 5
1 3 2 4 5
2 1 0 2 5
2 1 1 2 1
2 4 1 1 2样例输出
min=29
min=11
这道题用dfs+剪枝求解。剪枝在三个方面:
1. 用数组vis[i][j]进行记忆化搜索,不再访问已访问过的点;
2. 如果走到终点前的任意某点时,花费的时间已经比已知的最短总时要多,则剪掉;
3. 用数组dp[x][y]来更新每次走到点(x,y)时所花费的最短时间,若此次路线来到点(x,y)花费的时间比原来的还多,那么这种方案必然不是最优;
代码如下。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>using namespace std;const int MAXSIZE = 101;int map[MAXSIZE][MAXSIZE], vis[MAXSIZE][MAXSIZE], dp[MAXSIZE][MAXSIZE];
int n, ans;const int dx[] = { 0,1,-1,0 };
const int dy[] = { 1,0,0,-1 };void init_map()
{memset(vis, 0, sizeof(vis));memset(dp, 0x7f, sizeof(dp)); //设为无穷大值for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)scanf("%d", &map[i][j]);
}bool In(int x, int y) //判断点(x,y)是否合法
{if (x<1 || x>n || y<1 | y>n)return false;return true;
}void dfs(int x, int y, int time) //(x,y)是当前位置的坐标,time是已花费时间
{if (x == n&&y == n) //到达终点{ans = min(time + map[x][y], ans); //更新最短时间return;}if (time >= ans || time >= dp[x][y]) return; //剪枝,1.当前花费的时间已经大于最短总时;2.本次来到当前点花费的时间比原来的多dp[x][y] = time;for (int i = 0; i < 4; i++){if (In(x + dx[i], y + dy[i]) && map[x][y] != 0 && !vis[x + dx[i]][y + dy[i]]){vis[x + dx[i]][y + dy[i]] = 1; //标记点(x,y)为已访问状态dfs(x + dx[i], y + dy[i], time + map[x][y]);vis[x + dx[i]][y + dy[i]] = 0; //还原}}
}int main()
{while (scanf("%d", &n) != EOF){init_map();ans = 0x7ffffff;vis[1][1] = 1;dfs(1, 1, 0);printf("min=%d\n", ans);}return 0;
}
HNUST 挑战ACM迷宫(DFS)相关推荐
- 搜索专题:问题 E: 挑战ACM迷宫
这是往年校赛的一道题,最开始做这道题的时候还没有系统的学习过搜索,用了C语言学的回溯法尝试,毫无疑问的TLE: 学习了DFS之后,自己的剪枝功力不够,又是TLE,最后学了BFS之后,哇,终于做出来了, ...
- K - 老鼠走迷宫(DFS)
Description 现在一只老鼠被困在了迷宫里!你需要判断老鼠能否走出迷宫. 老鼠只能向上下左右四个方向移动.我们认为只要老鼠走到了迷宫的边界即算走出迷宫. Input 第一行输入两个整数 n, ...
- P1605 迷宫 dfs回溯法
题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...
- 蓝桥杯2017初赛-迷宫-dfs
题目描述 X星球的一处迷宫游乐场建在某个小山坡上.它是由10x10相互连通的小房间组成的. 房间的地板上写着一个很大的字母.我们假设玩家是面朝上坡的方向站立,则: L表示走到左边的房间,R表示走到右边 ...
- [蓝桥杯2019初赛]迷宫-DFS、BFS两种方法
迷宫问题的最短路,加最小字典序 迷宫文件maze.txt传送门 作者写的2019年B组蓝桥杯解集 . . . DFS的版本 #include<iostream> #include<c ...
- 【upc 15305】 迷宫(DFS+BFS)
题目描述 迷宫的管理员们决定在新开始的季节里使用新的墙纸.出于这个目的他们需要一个程序来计算迷宫内墙壁的面积.这就是你即将要做的工作. 我们把这个迷宫用一个NN(3<=N<=33)的矩阵表 ...
- 【ACM】DFS 全排列 回溯
深入体会一下DFS,回溯 在一些OJ上endl和"\n"还是有区别的!!! 题目链接:http://codevs.cn/problem/1294/ 方法一: #include &l ...
- 洛谷 P1141 01迷宫(dfs)
https://www.luogu.org/problem/P1141 思路:找到每一个连通块,不同连通块的标记不同,给标记赋值成该连通块的数量 1 // luogu-judger-enable-o2 ...
- 海龟 (turtle) 画图终极实战:小海龟挑战大迷宫游戏
文章目录 1. 需求分析 2. 系统设计 2.1 游戏功能结构 2.2 游戏业务流程 2.3 系统预览 3. 系统开发必备 3.1 系统开发环境 3.2 文件夹组织结构 4. 主窗口设计 5. 游戏地 ...
最新文章
- 建立一个php 基础类
- Java和Android中一些常用的公共方法
- (实用)将wordpad添加到Windows PowerShell中
- Spring Cloud构建微服务
- 【Java】线程通信的例子:用两个线程打印 1-100;生产者消费者问题
- 代码 拉取_Git 利用 Webhooks 实现代码的自动拉取
- react jest测试_如何设置Jest和Enzyme来测试React Native应用
- oracle dataguard 03113 error code solution
- java写html的多选框,Selenium+java - 单选框及复选框处理
- 使用EF框架的增删改查和分页的公共类
- 三段式状态机_verilog
- android TextView属性汇总
- Vue-01 —创建一个Vue实例
- 常见软件非功能性需求描述案例
- 二阶魔方还原 C++ BFS
- 命令查看计算机出厂时间,Check cosmetics or perfume production date and shelf life by the batch code....
- 如何查看mysql的gtid_mode_配置MHA开启主从同步的时候会提示从库gtid_mode为ON的状态...
- slice,splice,split的区别,一开就懂
- 哪种无线耳机音质最好?盘点2023四款好音质蓝牙耳机
- Matlab数学建模(七):连续模型