搜索分为DFS(图论):深度优先搜索,是一种用于遍历或搜索树或图的算法,所谓优先,就是说每次都尝试向更深的节点走。
在搜索算法中,该DFS常常指利用递归方便地实现暴力枚举的算法,与图论中的DFS算法有一定相似之处,但并不完全相同,通常是:构造一棵搜索树进行搜索。
例题洛谷P1706
思路:先定义洛谷数组,一个用于存放合法解,一个用来标记该数是否用过。
我们可以先写一个用于打印的函数print(),每当深搜时找到一个符合条件的解时,则输出一下,输出这个解(注意题目的输出形式--五个场宽)。
接下来就是写基于递归的深搜函数了,主要思路:先判断格子是否填满了,如果填满则printf。如果没有填满,则开始循环,在循环中先判断当前填的数是否用过,如果没有,则填入,搜索下一格。(需要回溯)
回溯就是要消除搜索过程中的不同的可能性之间对中间变量的影响,即搜索下一个答案之前,保证上一个答案对下一个答案没影响,恢复到之前的状态。
时间复杂度O(n!)
#include
#include
using namespace std;
int ans[15];
bool f[15];//f[i]==0,i没有用过
int n;
void printff() {
for (int i = 1; i <= n; i++) {
printf("%5d", ans[i]);
}
printf("\n");
}
void dfs(int k) {
if (k > n) {
printff();
return;
}
for (int i = 1; i <= n; i++) {
if (f[i] == 0) {
ans[k] = i;//没用过
f[i] = 1;//改为用过状态
dfs(k + 1);
f[i] = 0;//回溯到初始状态
}
}
}
int main() {
scanf("%d", &n);
dfs(1);
return 0;
}
适用于海洋大陆,岛屿数量问题,迷宫问题......
缺点:时间复杂度高,枚举----优化在后续,敬请期待......
例题力扣200 无向图,找连通块
思路:DFS,设目前在(i,j)点,搜索(i,j)所在的整个岛屿,从(i,j)向上下左右四个方向进行搜索(i-1,j)(i+1,j),(i,j-1),(i,j+1)。若这四个点为‘1’,且不确界,则可以走过去,改为‘0’,再以走到的点为基础进行搜索。
#include
#include
#include
using namespace std;
void dfs(vector>& grid, int i, int j) {
int n = grid.size();
int m = grid[0].size();
grid[i][j] = '0';
if (i - 1 >= 0 && grid[i - 1][j] == '1')dfs(grid, i - 1, j);
if (i + 1 < n && grid[i + 1][j] == '1')dfs(grid, i + 1, j);
if (j - 1 >= 0 && grid[i][j - 1] == '1')dfs(grid, i, j - 1);
if (j + 1 < m && grid[i][j + 1] == '1')dfs(grid, i, j + 1);
}
int numIslands(vector>& grid) {
int n = grid.size();
int m = grid[0].size();
int num = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '1') {
num++;
dfs(grid, i, j);
}
}
}
return num;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
vector>g(n, vector(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
getchar();
scanf("%c", &g[i][j]);
}
}
int ans = numIslands(g);
printf("%d", ans);
return 0;
}
搜索分为DFS和BFS
DFS图论:树 图的遍历 基于搜索树或者状态树的枚举题目 基于表格搜索三个(通过DFS找到/搜索所有的可能性
#include
#include
#include
using namespace std;
void dfs(vector>& grid, int i, int j) {
int n = grid.size();
int m = grid[0].size();
grid[i][j] = '0';
if (i - 1 >= 0 && grid[i - 1][j] == '1')dfs(grid, i - 1, j);
if (i + 1 < n && grid[i + 1][j] == '1')dfs(grid, i + 1, j);
if (j - 1 >= 0 && grid[i][j - 1] == '1')dfs(grid, i, j - 1);
if (j + 1 < m && grid[i][j + 1] == '1')dfs(grid, i, j + 1);
}
int numIslands(vector>& grid) {
int n = grid.size();
int m = grid[0].size();
int num = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '1') {
num++;
dfs(grid, i, j);
}
}
}
return num;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
vector>g(n, vector(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
getchar();
scanf("%c", &g[i][j]);
}
}
int ans = numIslands(g);
printf("%d", ans);
return 0;
}