深度优先搜索刷题(方向数组+DFS思想):解决矩阵单词搜索问题的标准解法

例1

代码实现

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
int n;
void dfs(int sum, int last, vector<int>path)
{
	if (sum == n)
	{
		for (int i = 0; i < path.size(); i++)
		{
			cout << path[i];
			if (i != path.size() - 1)
			{
				cout << "+";
			}
		}
		cout << endl;
	}
	for (int i = last; i <= n - sum; i++)
	{
		if (i == n)  break ;
		path.push_back(i);
		dfs(sum + i,i, path);
		path.pop_back();
	}
}
int main()
{
	cin >> n;
	vector<int>path;
	dfs(0, 1, path);
	return 0;
}

解析:

递归函数设计
cpp 复制代码
void dfs(int sum, int last, vector<int>& path) {
    // 终止条件:找到完整拆分
    if (sum == n) {
        outputPath(path);
        return;
    }
    
    // 搜索策略:从last开始枚举,保证递增
    for (int i = last; i <= n - sum; i++) {
        // 选择当前数字
        path.push_back(i);
        // 递归探索
        dfs(sum + i, i, path);
        // 回溯:撤销选择
        path.pop_back();
    }
}

比如最开始dfs参数为(0,1,path);last对应1,开始枚举1的所有可能,1的可能罗列完之后,那些数组都会回溯,回溯到开始,由2开始继续枚举搜索,由此循环;

i<=n-sum是保证加的数字单调递增,如果剩下的数字(n-sum)大于i,那么就不可能单调递增;

如果不满足for循环,就会跳出当前函数,回溯到上一个,然后pop_back最后那个元素,

就用7举例,7个1相加,最后第7个1加完之后,第八个1不满足for循环了,输出这次的结果,跳出来,回溯,pop_back第7个1,进行for循环,发现也不满足,继续回溯,回溯到第6个1,删除,for循环,发现2刚刚好,于是就把最后两个1换成2了,然后继续输出答案,以此类推

例2

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
int dx[8] = { -1,-1,-1,0,0,1,1,1 };
int dy[8] = { -1,0,1,-1,1,-1,0,1 };
int n;
vector<string>grid;
vector<vector<bool>>mark;
const string word = "yizhong";
bool inground(int x, int y)
{
	if (x < 0 || x >= n || y < 0 || y >= n)
	{
		return false;
	}
	else return true;
}
void check(int x, int y)
{
	for (int i = 0; i < 8; i++)
	{
		bool vaild = true;
		for (int k = 0; k < word.size(); k++)
		{
			int nx = x + k * dx[i];
			int ny = y + k * dy[i];
			if (!inground(nx, ny) || grid[nx][ny] != word[k])
			{
				vaild = false;
				break;
			}
		}
		if (vaild)
		{
			for (int k = 0; k < word.size(); k++)
			{
				int nx = x + k * dx[i];
				int ny = y + k * dy[i];
				mark[nx][ny] = true;
			}
		}
	}
}
int main()
{
	cin >> n;
	grid.resize(n);
	mark.resize(n, vector<bool>(n,false));
	for (int i = 0; i < n; i++)
	{
		cin >> grid[i];
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (grid[i][j] == 'y')
			{
				check(i, j);
			}
		}
	}
	//输出 
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (mark[i][j])
			{
				cout << grid[i][j];
			}
			else {
				cout << "*";
			}
		}
		cout << endl;
	}
	return 0;
}

类似于深度优先搜索:

思路大概就是遍历二维数组,找到'y'这个字符,因为这个是yizhong的开始首字符,找到这个之后,对这个的8个方向,即左上,上,右上,左,右,左下,下,右下,八个方向逐一检查(搜索),for循环k那部分就是按照一个方向向下走,先锁定这一个方向,按这个路走下去,k乘每个方向就是叠加,k乘一个左边方向就是这个字母向左一个,k乘2个左边方向就是这个字母顺左边向左两个字母,以此类推;找到满足的方向就把那个路径标记为true;最后输出答案时,true的就输出字母,否则输出*星号;

相关推荐
寻寻觅觅☆5 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
偷吃的耗子5 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
化学在逃硬闯CS6 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar1236 小时前
C++使用format
开发语言·c++·算法
Gofarlic_OMS7 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
夏鹏今天学习了吗7 小时前
【LeetCode热题100(100/100)】数据流的中位数
算法·leetcode·职场和发展
忙什么果8 小时前
上位机、下位机、FPGA、算法放在哪层合适?
算法·fpga开发
董董灿是个攻城狮8 小时前
AI 视觉连载4:YUV 的图像表示
算法
ArturiaZ9 小时前
【day24】
c++·算法·图论
大江东去浪淘尽千古风流人物9 小时前
【SLAM】Hydra-Foundations 层次化空间感知:机器人如何像人类一样理解3D环境
深度学习·算法·3d·机器人·概率论·slam