C++一本通基础算法:深度优先搜索(DFS)

2023-11-11

算法概述:搜索,类似于枚举,从头结点开始,搜索发现有一些路可以走,先选择一条,走到一个结点处,重复上述过程,一直走到不能走为止,然后返回上一个结点,选择第二条路,一直检索知道将头结点所有的路走完。

算法图像

 如图所示,从1开始,发现可以到达2,开始递归调用,到达2的位置,然后发现,从2可以到达3,再递归调用,到达3,发现3不能再走了,返回到2,发现从2还可以到4,递归调用到达4,发现4也不能走,再次回到2,……,直到2所有的路都走完以后,返回到1,发现从1可以到6,……,当6所有的路径也走完之后,回到1,此时1已经没有任何可以走的路径了,搜索结束。

算法特点:和枚举一样要计算所有的结果,但与枚举不同的是,枚举的循环层数一定,但深度优先搜索的层数不为定值。

搜索部分代码的一般格式

void dfs (int x,int p) {	//x代表当前搜索层数,p决定下一次递归的大范围 
	if ( ) {           		//如果满足终止条件(找到一组解) 
					   		//执行操作 
		return;				//返回上一个函数 
	}
	for (int i = p + 1; ;i++) {
		if ( ) {			//如果当前i满足递归条件 
							//更新条件数组 
			dfs (x + 1,i);  //递归 
							//回溯,将条件数组变回原样(有时可以省略) 
		}
	}
}

题目链接

信息学奥赛一本通(C++版)在线评测系统

分析:每一组输出要按数字的升序输出,各组数据也要按字典序升序输出,故可以考虑搜索来枚举所有的可能性

代码

#include <iostream>
using namespace std;

int n, r, a[22], l = 0;

void search (int x,int y) {
	if (y == r) {
		for (int i = 0;i < l;i++) {
			if (a[i] / 10 == 0) cout << "  " << a[i];
			else cout  << " " << a[i];
		}
		cout << endl;
		return;
	}
	else {
		for (int i = x + 1;i <= n - r + y + 1;i++) {
			a[l++] = i;
			search(i,y + 1);
			a[--l] = 0;
		}
	}
}

int main () {
	cin >> n >> r;
	search (0,0);
	return 0;
}

题目链接

信息学奥赛一本通(C++版)在线评测系统

分析:走迷宫,从当前位置向前后左右四个方向走,先判断四个位置是否是墙,是否走过,或越界,如果都没有,那么走向这个位置。如果搜索结束后还没有搜索到终点位置,则无法走到。

代码

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

const int N = 110;
int w[4][2] = {0,1,1,0,0,-1,-1,0},ha,hb,la,lb;
bool m[N][N],flag = 0; 

void dfs (int x,int y) {
	if (x == hb && y == lb) {
		flag = 1;
		return;
	}
	for (int i = 0;i < 4;i++) {
		int nx = x + w[i][0],ny = y + w[i][1];
		if(m[nx][ny]) {
			m[nx][ny] = 0;
			dfs(nx,ny);
		}
	}
}

int main () {
	int n, k;
	cin >> k;
	while (k--) {
		memset (m,0,sizeof(m));
		flag = 0;
		cin >> n;
		for (int i = 1;i <= n;i++) {
			for (int j = 1;j <= n;j++) {
				char u;
				cin >> u;
				if (u == '.') m[i][j] = 1;
				else m[i][j] = 0;
			}
		}
		cin >> ha >> la >> hb >> lb;
		ha++;hb++;la++;lb++;
		if (!m[ha][la] || !m[hb][lb]) cout << "NO" << endl;
		else {
			dfs(ha,la);
			if (flag) cout << "YES" << endl;
			else cout << "NO" << endl;
		}
	}
	return 0;
} 

敲黑板

搜索最阴间难的题目:八皇后问题

皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 × 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。

分析:

:所有的皇后都不在一行上,不妨我们从第一行开始,每行只放置一个皇后,这样即可保证皇后不能在同一行的问题。

列:建立一个布尔数组,每放置一个皇后,就把皇后所处列的这一项设为1,在放置皇后之前,先判断这个皇后所在列的这一项是否为1.

从左上到右下的对角线

观察这个表格可知,如果两个方格的行与列的差相同,则这两个方格位于同一条对角线上。

从右上到左下的对角线:

同理,观察表格可知,如果两个方格的行与列的和相同,则这两个方格位于同一条对角线上。

八皇后代码(dfs部分)

int a[93][8];
bool lx[20],rx[20],s[10];
int p,k[9];

void search (int h) {
	if (h > 8) {
		p++;
		for (int i = 0;i < 8;i++) {
			a[p][i] = k[i];                //a[p]为八皇后的第p组解,八皇后问题共有92组解
		}
		return;
	}
	for (int i = 1;i <= 8;i++) {
		if (!lx[i + h] && !rx[h - i + 8] && !s[i]) {
			lx[i + h] = 1;
			rx[h - i + 8] = 1;
			s[i] = 1;
			k[h - 1] = i;
			search (h + 1);
			k[h - 1] = 0;
			lx[i + h] = 0;
			rx[h - i + 8] = 0;
			s[i] = 0;
		}
	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++一本通基础算法:深度优先搜索(DFS) 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • jdk1.8.191 JVM内存参数 InitialRAMPercentage和MinRAMPercentage

    MaxRAMPercentage InitialRAMPercentage MinRAMPercentage 这三个参数是JDK8U191为适配Docker容器新增的几个参数 类比Xmx Xms 至于 XX InitialRAMFracti
  • 物联网安全概述

    什么是物联网 在你学习有关IPv6的时候 你的老师或许说过 有一天在你的房子每个设备都会有一个IP 物联网基本上就是处理每天的事务 并把它们连接到互联网上 一些常见的物联网设备 如灯光 窗帘 空调 也有像冰箱这样的不太常见的设备 甚至一个卫
  • [sicily] 1003. 相连的1

    声明 原题目转载自中山大学sicily平台 解答部分为原创 Problem 对于一个01矩阵A 求其中有多少片连成一片的1 每个1可以和上下左右的1相连 请为下面的Solution类实现解决这一问题的函数countConnectedOnes
  • 聚合支付行业术语,你get到了吗?

    俗话说 内行看门道外行凑热闹 每一个行业都有它独特的专业术语 对于外行人来说 这些专业术语就跟专有名词一样难懂 支付行业也是一样 因为是近几年的新兴行业 很多人对这一行不懂 甚至一些在支付行业工作的人 对这一行的很多名词概念也很模糊 认知仅
  • 基础篇(二):内存屏障是什么

    目录 前置知识 内存屏障 什么是内存屏障 作用 内存屏障的分类 1 强制读取 刷新主内存的屏障 强制刷新主内存 Load屏障 强制读取主内存 Store屏障 总结 2 禁止指令重排序的屏障 LoadLoad屏障 StoreStore屏障 L
  • 怎么修改游戏内存服务器,修改游戏服务器内存

    修改游戏服务器内存 内容精选 换一换 当您成功创建私有镜像后 镜像的状态为 正常 您可以使用该镜像创建服务器实例或云硬盘 也可以将镜像共享给其他帐号 或者复制镜像到其他区域 私有镜像的生命周期如图1所示 通过华为云创建的ECS服务器默认使用
  • mysql客户端小海豚_MySQL基础

    1 数据库概述 1 1数据的存储方式 第一种存储方式是创建对象 实际上new出来的对象不就是用来存数据的嘛 创建对象就是在堆内存中为对象请求了一个空间 相当于是将对象存入堆内存 第二种方式存文件中 这个在IO流部分我们就是这么处理的 但是缺
  • Python批量改文件名

    对以下路径中的文件名批量修改 文章目录 一 读取指定路径中的文件名 二 正则表达式提取需要保留的部分 1 介绍re库 2 re库中函数的用法 1 re findall 最常用 2 re sub pattern repl string cou
  • 数仓知识点

    传统数仓知识 1 数据仓库分层 ODS 数据准备层 该区为数据仓的准备区 直接输入源数据 如业务库 埋点日志和消息队列等 DWD 数据细节层 该层为业务层和数据层的隔离层 保持和ODS层相同的颗粒度 该层还进行了数据清洗和规范化操作 例如去
  • 阿里巴巴笔试-2020.7.27-第二题 藏宝架

    题目 有个藏宝架有n层 每层的宝物数量不一 每个宝物都有其价值 现在要求拿出m个宝物 并且需要遵守规则 每次只能拿选定层的两端的宝物 要拿出的m个宝物的总价值是各种方案里最大的 输入 第一行是 n 和 m 后面每一行是各层的数据 n m 下
  • WebSocket 基于JAVA Spring boot Spring Colud 的使用

    先上代码再看调试结果 package com qiang user util import com alibaba fastjson JSONObject import org springframework stereotype Comp
  • 软考网络工程师-最新最全小白攻略

    一 前言 最近Beau 博主本人 也是考取了2023年上半年的软考网络工程师 这里也准备给小白们做一些避坑流程 这里附上通过图 二 考前准备 1 报考条件 无 无年龄 资质 学历限制 无需通过软考初级才能报考 是中国守法公民即可报名 2 考
  • webpack 保存文件后自动打包_自动打包插件webpack-dev-server的安装、配置及使用

    1 介绍 webpack dev server插件可以实现Webpack的自动打包编译 这样 就不需要每次修改完代码都重新手动输入webpack打包了 2 安装 在项目的根路径下输入 cnpm i webpack dev server D
  • Python----模块(Module)和包(Package)

    Python 包 包 定义 为了组织好模块 会将多个模块分为包 Python 处理包也是相当方便的 简单来说 包就是文件夹 但该文件夹下必须存在 init py 文件 常见的包结构如下 最简单的情况下 只需要一个空的 init py 文件即
  • uniapp中使用网页录音并上传声音文件(发语音)——js-audio-recorder的使用【伸手党福利】

    uniapp中上传音频只能在app或小程序当中实现 如何使用网页完成语音的录制和上传则成为了困扰前端童鞋的重点 本文着重解决 js audio recorder报 error 浏览器不支持getUserMedia 的问题 js audio
  • qt使用socket连续发图片,服务端使用qt或者python接受图片

    首先客户端是用qt 不能用python这种 首先在pro里面 QT network 然后引入头文件 include
  • 2023最新AI创作商用ChatGPT源码分享+支持AI绘画

    一 SparkAI智能创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统 本期针对源码系统整体测试下来非常完美 可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统 那么如何搭建部
  • Vue 中使用 Upload 组件上传 Excel

    vue 中使用 Element 的 upload 组件上传 Excel 大致可以分两种情况 使用 action 上传到服务器 使用 axios 上传到服务器 注意 上传文件可能由于前后端格式不统一导致上传失败 application x w
  • openTLD算法在opencv3的PatchGenerator

    由于opencv3的各种版本相对于opencv2的版本已经改变了很多内容 openTLD跟踪算法所依赖的一些函数在opencv3中已经消失了 为此需要对openTLD进行适当修改才能使之在opencv3的各种版本中运行 加入如下文件 并在对
  • C++一本通基础算法:深度优先搜索(DFS)

    算法概述 搜索 类似于枚举 从头结点开始 搜索发现有一些路可以走 先选择一条 走到一个结点处 重复上述过程 一直走到不能走为止 然后返回上一个结点 选择第二条路 一直检索知道将头结点所有的路走完 算法图像 如图所示 从1开始 发现可以到达2