算法07 深度优先搜索及相关问题详解

深搜与广搜是搜索算法中最常用的两种算法,通过深度优先搜索解决问题还会用到回溯和剪枝,让我们一起进入本章,了解深搜的基本概念和模板,并学会解决一些常见问题。

目录

问题导入

走迷宫问题

如何走?

问题建模

如何表示迷宫地图等信息呢?

如何表示每次移动的过程?

走迷宫问题参考程序

深度优先搜索概述

解决问题时的注意事项

训练:迷宫

参考代码

训练:全排列问题

参考代码


问题导入

走迷宫问题

现在有一个3*3的迷宫,小知在迷宫的左上角,迷宫出口在右下角,请你帮小知算一算,他有多少种方案可以走出迷宫(每个格子不能重复走动)。

迷宫中显示0的点,是不可以走的。小知每次只能到达相邻的上下左右4个格子。

如何走?

1.如果当前出发的格子是终点,则程序结束。

2.每次可以选择的格子有:上(A)、下(B)、左(C)、右(D)。

3.按照顺序尝试每个格子是否可走。

4.找到第一个可以走的格子(假设为B),标记该格子,表示已经走过。

5.再从格子(B)出发,重复上述过程(递归进行)。

6.将格子(B)消除标记,再尝试从格子(C、D)出发去找路线。

 

问题建模

如何表示迷宫地图等信息呢?

使用一个3*3的二维数组maze[][]来存储迷宫信息,如果值位0表示不可走,1表示可走。

使用一个3*3的二维数组used[][]来标记是否走过,没走过为0,走过的话为1。

例:used[1][2]=1,表示maze[1][2]已经走过。

如何表示每次移动的过程?

每次移动,实际上就是坐标的变化。

上:行标-1,列标不变。

下:行标+1,列标不变。

左:行标不变,列标-1。

右:行标不变,列标+1。

我们可以用一个二维数组表示移动的方向。

例:当前坐标为(1,2),向上移动就是:(1+fx[0][0],2+fx[0][1]),得到(0,2)。

 

走迷宫问题参考程序

int ans=0,maze[6][6],used[6][6],fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void dfs(int x,int y){if(x==3&&y==3){ //如果当前找的点就是终点,则方案数+1,结束本次搜索。ans++; return ;}else{used[x][y]=1;  //将当前所在的点标记为1,表示走过for(int i=0;i<4;i++) { //尝试上、下、左、右4个方向int nx=x+fx[i][0];int ny=y+fx[i][1]; //下一次查找的点的坐标nx,ny//nx,ny要在地图内,并且可走,并且未被走过。if(nx>=1&&nx<=3&&ny>=1&&ny<=3&&used[nx][ny]==0&&maze[nx][ny]==1){used[nx][ny]=1;  //表示nx,ny表示走过dfs(nx,ny); //从nx,ny再去找used[nx][ny]=0; //消除标记,再尝试其他方向。}}used[x][y]=0; //消除标记}
}int main(){for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){cin>>maze[i][j];}}dfs(1,1);cout<<ans;return 0;
}

深度优先搜索概述

我们走迷宫的过程就是一个深度优先搜索的过程:从可以解决问题的某一个方向出发,并一直深入寻找,找到这个方向可以得到的所有解决方案,如果找不到,则回退到上一步,从另一个方向开始,再次深入寻找。

解决问题时的注意事项

1.首先弄清楚问题的解空间,即迷宫有多大。

2.弄清楚搜索的边界,即到哪一步就该停下,不用再搜。

3.搜索的方向,即可能包含哪几种子问题。

void dfs()//参数用来表示状态  
{  if(到达终点状态){  ...//根据题意添加  return;  }  if(越界或者是不合法状态)  return;  if(特殊状态)//剪枝return ;for(所有可能的下一状态){  if(状态符合条件){  修改操作;//根据题意来添加  标记;  dfs();  (还原标记);  //是否还原标记根据题意  //如果加上(还原标记)就是 回溯法  }  }  
}

训练:迷宫

给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

【输入描述】第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。

【输出描述】给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。

【输入样例】2 2 1

1 1 2 2

1 2

【输出样例】1

参考代码

#include<bits/stdc++.h>
using namespace std;int ans=0,maze[6][6],used[6][6];
int Fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m,t,sx,sy,fx,fy,tx,ty;void dfs(int x,int y,int s,int e){if(x==s&&y==e){ans++; return ;}else{used[x][y]=1;for(int i=0;i<4;i++) {int nx=x+Fx[i][0];int ny=y+Fx[i][1];if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&used[nx][ny]==0&&maze[nx][ny]==0){ used[nx][ny]=1;dfs(nx,ny,s,e);used[nx][ny]=0;}}used[x][y]=0;}
}int main(){cin>>n>>m>>t;cin>>sx>>sy>>fx>>fy;for(int i=1;i<=t;i++){cin>>tx>>ty;maze[tx][ty]=1;}dfs(sx,sy,fx,fy);cout<<ans;return 0;
}

训练:全排列问题

输入整数n(n<=9),输出1~n的所有排列方式。

例:n=3,全排列为123,132,213,231,312,321。

【输入描述】输入一个正整数n

【输出描述】输出1~n之间的全排列(n<=9),换行输出

【输入样例】3

【输出样例】123

132

213

231

321

312

参考代码

int ans[10],used[10];
void dfs(int x,int n){if(x>n){for(int i=1;i<=n;i++)cout<<ans[i];cout<<endl;return;}for(int i=1;i<=n;i++){if(!used[i]){ans[x]=i;used[i]=1;dfs(x+1,n);used[i]=0;}}
}
int main(){int n;cin>>n;dfs(1,n);return 0;
}

从入门到算法,再到数据结构,查看全部文章请点击此处​​icon-default.png?t=N7T8http://www.bigbigli.com/ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/35122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于支持向量机的垃圾邮件分类,使用SVM+flask+vue

sms-classify 基于支持向量机的垃圾邮件分类&#xff0c;使用SVMflaskvue 数据集和源码地址 数据集 SMS Spam Collection Data Set 来源于 UCI。样例被分为非垃圾邮件&#xff08;86.6%&#xff09;和垃圾邮件&#xff08;13.4%&#xff09;&#xff0c;数据格式如下&#xff…

网络爬虫中Xpath的使用方法

正则表达式虽然可以处理包含了诸如 HTML 或 XML 内容的字符串&#xff0c;但只能根据文本的 特征匹配字符串&#xff0c;而忽略字符串所包含的内容的真实格式。为了解决这个问题&#xff0c;Python 引入 XPath 以及支持 XPath 的第三方库 lxml&#xff0c;专门对 XML 或 HTML 格…

minio+tusd+uppy搭建文件上传服务

1、docker部署minio、tusd服务 1.1 新建docker-compose.yml minio API: http://ip:9100 minio控制台: http://ip:9101 tus API: http://ip:9102/files/ tus webhooh: http:172.0.0.1:3000/files/webhooh(用户鉴权API) version: 3.7services:minio:image: minio/minio:RELEAS…

亚马逊运营专词(一)

许多新入驻亚马逊的大陆卖家&#xff0c;对亚马逊的专业词汇还不太了解&#xff0c;导致在运营店铺的过程出现一些问题&#xff0c;今天就来讲解一下亚马逊常用的运营专词&#xff0c;方便新手卖家深入了解。 1. Listing&#xff1a;亚马逊listing指的是产品的详情页面&#xf…

【Feature Pyramid Networks for Object Detection】

Feature Pyramid Networks for Object Detection 摘要引言2 相关工作3 FPN4 应用摘要 特征金字塔是识别系统中用于检测不同尺度对象的基本组件。但是,最近的深度学习对象检测器已经避免了金字塔表示,部分原因是它们在计算和内存方面都很密集。在这篇论文中,我们利用深度卷积…

Java面试题:聚簇索引和非聚簇索引

聚簇索引和非聚簇索引 聚簇索引(聚集索引) 将数据的存储和索引放在一块,索引结构的叶子节点保存了行数据 索引字段必须存在,且只能存在一个 非聚集索引(二级索引) 将数据和索引分开存储,索引结构的叶子节点关联的是对应的主键 索引字段可以存在多个 索引的选取规则 如果…

豆瓣高分项目管理书籍推荐

&#x1f4ec;豆瓣网站上有很多项目管理领域的书籍获得了较高的评分&#xff0c;以下是一些高分项目管理书籍的精选列表&#xff0c;发出来跟大家分享一下&#xff1a; 《项目管理知识体系指南&#xff08;PMBOK指南&#xff09;》 【内容简介】这本书是美国项目管理协会&…

onnx模型修改:去掉Dropout层

文章目录 尝试1&#xff1a;强行设置dropout层train mode为False尝试2&#xff1a;找到onnx模型中的dropout, train mode设置为False尝试3&#xff1a;直接删除dropout层&#xff0c;连接其输入输出结语 最近训练模型使用了tinyvit&#xff0c;性能挺强的&#xff1a; 但是导出…

超细毛搭配超宽设计,一款更呵护牙龈的牙刷

牙龈敏感的时候&#xff0c;刷牙特别难受&#xff0c;最近试了试惠百施&#xff08;EBISU&#xff09;65孔宽头软毛牙刷&#xff0c;感觉它的口腔护理体验很不错。这款牙刷的设计独特&#xff0c;采用宽头设计&#xff0c;一次就能刷两排牙齿&#xff0c;极大地提高了清洁效率。…

RS232自由转Profinet协议网关模块连接1200PLC与扫码枪通讯及手动清零案例

一、RS232和Profinet这两种通讯接口的特点和应用场景&#xff1a; RS232是一种串行通讯接口标准&#xff0c;常用于连接计算机和外部设备&#xff0c;传输速率较低但稳定可靠。Profinet则是一种工业以太网通讯协议&#xff0c;具有高速、实时性强的特点&#xff0c;适用于工业…

【C语言】解决C语言报错:Dangling Pointer

文章目录 简介什么是Dangling PointerDangling Pointer的常见原因如何检测和调试Dangling Pointer解决Dangling Pointer的最佳实践详细实例解析示例1&#xff1a;释放内存后未将指针置为NULL示例2&#xff1a;返回指向局部变量的指针示例3&#xff1a;指针悬空后继续使用示例4&…

自编码器笔记

编码器解码器自编码器 先压缩特征&#xff0c;再通过特征还原。 判断还原的和原来的是否相等 encode data 在一个“潜在空间”里。它的用途是“深度学习”的核心-学习数据的特征并简化数据表示形式以寻找模式。 变分自编码器&#xff1a; 1. 首先、假设输入数据是符合正态分布…

【SQL Server点滴积累】Setup SQL Server 2008 Database Mirror (二)

【SQL Server点滴积累】Setup SQL Server 2008 Database Mirror (一)-CSDN博客今天分享SQL Server 2008 R2搭建数据库镜像(Database Mirror)https://blog.csdn.net/ncutyb123/article/details/139749117?spm1001.2014.3001.5501本篇Blog基于以上Blog步骤进行SQL Server 2008 R…

python03——文件操作(new)

“变量”open&#xff08;‘文件路径’&#xff0c;‘模式’&#xff09; //注意加引号 “变量”.write( ) //write函数是写的是字符串&#xff0c;如果你写的东西不是字符串&#xff0c;要写成write&#xff08;str&#xff08;。。&#xff09;&#xff09; “变量”.read…

vue3学习教程第四十节(pinia的用法注意事项解构store)

pinia 主要包括以下五部分&#xff0c;经常用到的是 store、state、getters、actions 以下使用说明&#xff0c;注意事项&#xff0c;仅限于 vue3 setup 语法糖中使用&#xff0c;若使用选项式 API 请直接查看官方文档&#xff1a; 一、前言&#xff1a; pinia 是为了探索 vu…

力扣算法-9.回文数

9.回文数 个人思考 首先从示例2可以看出符号也算在整数这个整体内&#xff0c;可以先判断整数若为负数则返回false其次很容易就会想到遍历两次&#xff0c;从头以及从尾&#xff0c;遍历得到的结果相比较&#xff0c;相同则为回文数 public class Alee9 {public static void …

【linux基础】后台执行命令,防止中断nohup

前台运行与后台运行&#xff1a;前台运行&#xff0c;就是运行过程一直在屏幕输出。 目的&#xff1a;1. 提交至后台 & 2.防止中断 nohup 1.终端上不要有大量的log出现&#xff0c;后台运行 (1) & 程序后台运行 #脚本、修改权限 vi test.sh chmod 777 test.sh#后…

ArcGIS Pro SDK (三)Addin控件 3 事件功能类

22 ArcGIS Pro 放置处理程序 目录 22 ArcGIS Pro 放置处理程序22.1 添加控件22.2 Code 23 ArcGIS Pro 构造工具23.1 添加控件23.2 Code 24 ArcGIS Pro 表构造工具24.1 添加控件24.2 Code 22.1 添加控件 22.2 Code 放置处理程序可以实现文件拖动放置、TreeVIew、ListBox等控件拖…

ArcGIS批量设置多图层的三调地类符号

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 01需求说明 这次我们要实现的是将多个地类图层批量符号化。比如将多个三调地类图斑批量符号化。 ​ 有什么好方法呢 &#xff1f; 我们可以将一个图层利用三调符号库进行…

Stable Diffusion 3 正式开源,超强文生图模型 SD3-M 上线,赶紧来试试吧!

前言 我们都知道 Stable Diffusion 3 是一款强大的文生图模型&#xff0c;拥有20亿参数&#xff0c;因其高效的推理速度和卓越的生成效果而备受瞩目。 近日&#xff0c;Stability AI在推特上宣布正式开源了 Stable Diffusion 3 Medium&#xff08;SD3-M&#xff09; 权重&…