搜索与回溯(深搜和广搜概念、定义、算法框架、及经典例题详讲加代码)

本文详细讲解了搜索与回溯算法,包括深度优先搜索(DFS)和回溯法的概念、算法框架及经典例题。DFS通过栈实现,适用于所有解的情况,而回溯法是DFS的一种控制策略,占用空间少。此外,文章还介绍了广度优先搜索(BFS)的基本思想和算法框架,以及多个相关例题的解题思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搜索和回溯

一、 概念

搜索是计算机程序设计中一种最基本、最常用的算法。搜索算法是直接基于计算机高速运算的
特点而使用的计算机求解方法。
它是从问题的初始状态出发,根据其中的约束条件,按照一定的策略,有序推进,不断深入,
对于达到的所有目标状态(解空间),一一验证,找到符合条件的解(可行解),或者找出所
有可行解中的最优解。

(一)、深度搜索

1、基本思想

深度优先搜索是将当前状态按照一定的规则顺序,先拓展一步得到一个新状态,
再对这个新状态递归拓展下去。如果无法拓展,则退回一步到上一个状态,再按
照原先设定的规则顺序重新寻找一个状态拓展。如此搜索,直至找到目标状态,
或者遍历完所有状态。所以,深度优先搜索也是一种“盲目”搜索。
对于图9.10-1所示的一个“无向图”,从顶点V0开始进行深度优先搜索,
得到的一个序列为:V0,V1,V2,V6,V5,V3,V4
在这里插入图片描述

2、深度优先搜索的算法框架

深度优先搜索(Depth First Search,DFS),简称深搜,
其状态“退回一步”的顺序符合“后进先出”的特点,
所以采用“栈”存储状态。深搜适用于要求所有解方案的题目。
深搜可以采用直接递归的方法实现,其算法框架如下:

void dfs(int dep, 参数表 );{
	自定义参数 ;
	if( 当前是目标状态 ){
		输出解或者作计数、评价处理 ;
	}else
		for(i = 1; i <= 状态的拓展可能数 ; i++)
			if( 第 i 种状态拓展可行 ){
				维护自定义参数 ;
				dfs(dep+1, 参数表 );
			}
}
3、典型例题
(1)、八皇后原始版本

题目描述

在国际象棋棋盘上(8*8)放置八个皇后,使得任意两个皇后之间不能在同一行,同一列,也不能位于同于对角线上。问共有多少种不同的方法,并且按字典序从小到大指出各种不同的放法。

输入格式

输出格式

1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5

总方法数

样例

样例输入

样例输出
1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5

92

解题思想
用深搜模拟当前棋盘上皇后的位置,判断当前位置可不可以放下皇后
若可以,储存下皇后的纵坐标,当8个皇后放完之后开始下一轮模拟,
直到找到最后一种解

代码实现

#include<cmath>
#include<cstdio>
int n,i,a[101],sum,w[101][10],j;
bool judge(int N)
{
	for(int j=1;j<N;j++)
	{
		if(abs(a[j]-a[N])==abs(j-N)||a[j]==a[N])
		{
			return false;
		}
	}
	return true;
}
void save()
{
	sum++;
	for(int j=1;j<=n;j++)
	{
		w[sum][j]=a[j];
	}
}
void solve(int i)
{
	if(i>n)
	{
		save();
		return ;
	}
	for(int j=1;j<=n;j++)
	{
		a[i]=j;
		if(judge(i))
		{
			solve(i+1);
		}
	}
}
int main()
{
	n=8;
	solve(1);
	for(i=1;i<=sum;i++)
	{
		for(j=1;j<=8;j++)
		{
			printf("%d ",w[i][j]);
		}
		printf("\n");
	}
	printf("%d",sum);
}
(2)、八皇后

题目描述

会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有 8 * 8 个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。对于某个满足要求的 8 皇后的摆放方法,定义一个皇后串 a 与之对应,即 a=b1b2…b8,其中 bi 为相应摆法中第 i 行皇后所处的列数。已经知道 8 皇后问题一共有 92 组解(即92个不同的皇后串)。 给出一个数 b,要求输出第 b 个串。串的比较是这样的:皇后串 x 置于皇后串 y 之前,当且仅当将 x 视为整数时比 y 小。

输入格式

第 1 行是测试数据的组数 n,后面跟着 n 行输入。每组测试数据占 1 行,包括一个正整数 b(1 <= b <= 92)。

输出格式

输出有 n 行,每行输出对应一个输入。输出应是一个正整数,是对应于 b 的皇后串。

样例

输入样例
2
1
92
输出样例
15863724
84136275

解题思想
利用上一题将所有皇后模拟出来的数组
直接打印对应组号就可以A掉

代码实现

#include<cmath>
#include<cstdio>
int n,i,a[101],sum,w[101][10],j,num,t;
bool judge(int N)
{
	for(int j=1;j<N;j++)
	{
		if(abs(a[j]-a[N])==abs(j-N)||a[j]==a[N])
		{
			return false;
		}
	}
	return true;
}
void save()
{
	sum++;
	for(int j=1;j<=n;j++)
	{
		w[sum][j]=a[j];
	}
}
void solve(int i)
{
	if(i>n)
	{
		save();
		return ;
	}
	for(int j=1;j<=n;j++)
	{
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值