必学算法——深度优先搜索(DFS)

深度优先搜索
深度优先搜索 (DFS, Depth-First Search) 是搜索的手段之一 。 它从某个状态开始, 不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直至找到最终的解。例如求解数独,首先在某个格子内填入适当的数字,然后再继续在下一个格子内埴入数字,如此继续下去。如果发现某个格子无解了,就放弃前一个格子上选择的数字,改用其他可行的数字。根据深度优先搜索的特点,采用递归函数实现比较简单。

**

部分和问题

给定整数a1…an,判断能否从中选择出若干个数祖成k
深度优先搜索(dfs)**


#include<iostream>
using namespace std;
int n,k;
int a[21];
//已经从前i项得到了和sum,然后对于i之后的进行分支 
bool dfs(int i, int sum)
{
    
    
	//如果前n项都计算过了,则返回sum和k是否相等 
	if(i==n) return sum==k;
	//加上a[i]的情况 
	if(dfs(i+1,sum+a[i])) return true;
	//不加上a[i]的情况 
	if(dfs(i+1,sum)) return true;
	//无论是否加上a[i]都不能凑成k的情况 
	return false;
}
int main()
{
    
    
	cin>>n;
	int i;
	for(i=0;i<n;i++)
	cin>>a[i];
	cin>>k;
	if(dfs(0,0))
	cout<<"Yes"<<endl;
	else
	cout<<"No"<<endl;
	return 0;
	
 } 

在这里插入图片描述
深度优先搜索从最开始的状态出发,遍历所有可以到达的状态。由此可以对所有的状态进行操作, 或者列举出所有的状态。
**

Lake Counting

**
有一个大小为MN的园子,雨后积起了水。八连通的积水被认为是连接在一起的。
请求出园子里共有多少水洼?(**八连通指的是下面图中相对W的
的部分**)


W


限制条件:
N,M≤100

输入
第一行包含两个正整数 N 和 M,表示将一个园子地面分成N*M块方格,N 行,M列,
接下来的 N 行描述了园子地面状况,其中‘W’表示积水的水洼,‘.’表示没有积水。
输出
仅一个数,表示水洼的总数。
输入示例
10 12
w…ww.
.www…www
…ww…ww.
…ww.
…w…
…w…w…
.w.w…ww.
w.w.w…w.
.w.w…w.
…w…w.
输出示例
3

前面说的情况明确指出是相对的情况,所以并不是说水洼一定要和最开始举例那个一模一样,形式结构上一样也可以算是水洼,接下来我们用dfs即可,从任意的w开始, 不停地把邻接的部分用 ' .'代替。 1次DFS后与初始的这个w连接的所有w就都被替换成了 ’ . ', 因此直到图中不再存在w为止, 总共进行DFS的次数就是答案了。 8个方向共对应了8种状态转移, 每个格子作为DFS的参数至多被调用一次, 所以复杂度为0(8xNxM)=O(Nx M)。*/

#include<iostream>
using namespace std;
int N,M;
char field[100][100];
void dfs(int x,int y)
{
    
    
	//将现在所在位置替换为.
	field[x][y]='.';
	//循环遍历移动的8个方向
	for(int dx=-1;dx<=1;dx++)
	for(int dy=-1;dy<=1;dy++)
	{
    
    
		//向x方向移动dx, 向y方向移动dy, 移动的结果为(nx,ny) 
		int nx=x+dx;
		int ny=y+dy;
		//判断(nx,ny)是不是在园子内, 以及是否有积水
		if(nx>=0&&nx<=N&&ny>=0&&ny<=M&&field[nx][ny]=='w')
		dfs(nx,ny);
	}
}
int main()
{
    
    
	cin>>N>>M;
	int i,j;
	int res=0;
	for(i=0;i<N;i++)
	for(j=0;j<M;j++)
	cin>>field[i][j];
	for(i=0;i<N;i++)
	for(j=0;j<M;j++)
	if(field[i][j]=='w')
	{
    
    
		//从有w的地方开始dfs
		dfs(i,j);
		res++;
	}
	cout<<res<<endl;
	return 0;	
}

结语
如果你觉得这篇博客还可以,别忘记点个赞加个关注再走哦。
如果你不嫌弃,还可以关注微信公众号———梦码城(持续更新中)
梦码在这里感激不敬

猜你喜欢

转载自blog.csdn.net/qq_45724216/article/details/107543738