DFS概念
它从某个状态开始,不断地转移状态直至无法转移,然后回退到前一步的状态,继续转移其他状态,如此不断重复,直至找到最终的解。
解题利用的是 递归函数。
例题
/*
dfs 例题
*/
//给定整数a1,a2,a3...an,判断是否能够从中抽出几个整数使得它们的和刚好为k
int a[Max];
int n, k;
bool dfs(int i, int sum);
int main()
{
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
cin >> k;
if (dfs(0, 0)) cout << "Yes\n";
else cout << "No\n";
}
bool dfs(int i, int sum)
{
//如果i与n相等 则返回它们的判断结果
if (i == n) return sum == k;
//如果深入进去满足就返回true
//加上那个整数 看是否满足
if (dfs(i + 1, sum + a[i])) return true;
//此处是 不加那个整数
if (dfs(i + 1, sum)) return true;
//如果深入进去不满足即返回false 供上一级判断
return false;
}
/*
计算水洼 dfs 例题
有一个大小为N * M的园子,雨后积起了水,八连通的水洼是认为连接在一起的,请你求出园子里的水洼
(八连通里的水相当于图中相对于‘w’的‘*’)
* * *
* W *
* * *
*/
#define n_Max 101
#define m_Max 101
#include <iostream>
using namespace std;
int n, m;
char filed[n_Max][m_Max]; //园子
void dfs(int x, int y);
int main()
{
//输入园子
cin >> n >> m;
int count = 0;//计
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> filed[i][j];
}
}
//计算水洼
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
//判断是否是水洼
if (filed[i][j] == 'w')
{
//对周围的水洼进行一次变换 顺便计数
dfs(i, j);
++count;
}
}
}
cout << count << endl;
}
void dfs(int x, int y)
{
filed[x][y] = '.';
int dx, dy;
//看其周围是否存在水洼 也就是 ‘w’
//相对于八连通来说 也就是中心的x,y坐标加上[-1,1]的值 然后判断是不是存在w
// i是横坐标
for (int i = -1; i <= 1; ++i)
{
//j是纵坐标
for (int j = -1; j <= 1; ++j)
{
dx = x + i;
dy = y + j;
//查看坐标是否是在满足题意的园子里 再判断周围有木有w 有就继续递归
if (dx >= 0 && dx < n && dy >= 0 && dy < m && filed[dx][dy] == 'w') dfs(dx, dy);
}
}
//没有就退出
return;
}