2015计算机学科夏令营上机考试G:The Game(DFS+回溯——全路径最优解)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目大意

模拟 “连连看” 游戏。
从给定的某‘X’位置移动到另一给定‘X’位置,要求路径直线数量最少,等价于转弯次数最少。

思路分析

这题很明显是一道搜索类的题目。

看到这题时,我的第一反应是,那道用优先队列的BFS的题目。但是这两题应该是完全不同的思路:
使用优先队列BFS的题目中,不同结点的搜索代价是存在差异的,因而可以使用优先队列对优先搜索方向进行约束;
而本题中往四个方向搜索的代价是相同的,也就是说所有结点都是等价的,因而无法用类似于优先队列这种约束性方法去强制性规定往“转弯次数最少”的方向优先搜索。

既然BFS无法解决,那么考虑DFS。
DFS是深度优先搜索,每次都是先对一个方向进行递归,也就是说尽最大可能走直线,这符合本题要求,因而是可行的。
设立一个vis[][]数组,0表示该位置未访问过,1~4分别代表搜索的四个方向。如果相邻两步所处位置的搜索方向相同则为直线,否则即为转弯,进行累加即可。
但我们要找的是最优解——转弯次数最小的路径,因而需要找到所有路径,这个时候需要进行回溯。要注意,回溯过程当中,不仅要将访问的结点状态恢复为“未访问”,还要将结果累加值恢复

辨析
  1. DFS过程中,是否需要回溯?
    如果只需要找到一条搜索路径即可,便不需要回溯;
    如果需要找到所有搜索路径,以求其最优解,就一定要回溯。
  2. 本题给出的代码,为什么DFS函数中的判断要写在for循环里,而不能写在外面?
    因为本题的起点、终点都为‘X’,是搜索过程中不能经过的地方。如果将判断写在for循环外面,那么起点也将进行进行一次判断,会导致无法开始进行递归;而将判断写在for循环里,则直接跳过了对于起点的判断,只需要对终点进行条件判断的处理即可。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 80;
const int INF = 0x3fffffff;

char map[maxn][maxn];
int vis[maxn][maxn]; // 1~4记录每个结点转弯状态,0表示该结点被访问过与否
int dx[4] = {
   1, -1, 0, 0};
int dy[4] 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值