迷宫系列(四)其他细节和DFS的实际应用(重要)

来源:互联网 发布:淘宝自动回复内容 编辑:程序博客网 时间:2024/05/29 18:46

一、其他细节

1.如何“走”迷宫

迷宫只允许向[上、下、左、右]四个方向前进,如果手写则过于麻烦,考虑每种移动对应的横纵坐标变化,有以下代码:

int dx[] = {-1, 0, 1, 0}; //上右下左int dy[] = {0, 1, 0, -1};

对于一个节点u,访问与它邻接的四个节点:

for (i = 0; i < 4; i++){  int cx = u.x + dx[i];  int cy = u.y + dy[i];  ......//other thing}

这里(cx,cy)即为节点u上下左右的坐标

2.如何把路径反映在迷宫里,像这样

d1

思路:

每找到一个解的时候输出整个迷宫,墙和起点终点的输出方式不改变,可以走的地方需要判断:若这个点在当前解中,则输出+ ,否则输出空格。

3.如何把路径改成箭头式的,像这样

这里写图片描述

思路:

对于每个在路径中的点,判断这个点前后两个点的坐标关系,来输出这个点的箭头形状,注意头尾两点要特殊考虑

二、DFS的应用(最实用!)

1.DFS的模板

DFS(状态a){  if (状态a标志着一个可行解)  {    处理这个解;  }  else  {    for (对于当前状态a可以扩展出的所有下一个状态b)    {      if(b符合约束条件) DFS(b);    }  }}

要注意在某些状态不能重复使用的问题中要进行标记(例如迷宫问题中的isVis属性)

2.隐式搜索问题

题目:两个乒乓球队进行比赛,各出三人。甲队为a, b, c三人,乙队为x, y, z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x, z比,请编程序找出三队赛手的名单。

对于这个问题,我们可以构造一棵搜索树,其中每个点对表示与(a,b,c)的对应对打选手

构造出来的搜索树如下:
u1

大部分搜索解的问题都可以转化为对一个隐式图的搜索,利用搜索算法可以得到解。

3.经典问题

①给定n个元素,选择m个元素进行排列(选排列问题)

例如:

(3,2)=> 12-13-21-23-31-32

问题变种:每个元素最多使用r次

例如:

(3,2,2)=> 11-12-13-21-22-23-31-32-33

②八皇后问题

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

③骑士游历问题

骑士游历是一个古老而著名的问题:在8×8格的国际象棋棋盘上,棋子马能否从某个格子出发按照“马跳日”的规则跳遍所有64个格子,最后再回到出发的那个格子?

问题①的伪代码:

DFS(解的长度len){  if(len == m) 输出当前解;  else  {    for (尚未被选择的元素A)    {      标记A被选择;A添加到答案的尾部;      DFS(len+1);      删除A的标记;A从答案尾部剔除;      }   }}主函数中调用DFS(0)即可

下一篇文章将公布DFS与BFS的迷宫代码= ̄ω ̄=

阅读全文
0 0
原创粉丝点击