深度优先搜索(DFS)

深度优先搜索(Depth-First-Search)是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索(暴力搜索)

DFS如同数据结构中的栈结构,是属于一种后进先出的结构,导致了所有的点进入栈时有一个顺序,我们称之为 “DFS序”。
在这里插入图片描述

DFS:从图中一个未访问的顶点 V 开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底…,不断递归重复此过程,直到所有的顶点都遍历完成,它的特点是不撞南墙不回头,先走完一条路,再换一条路继续走。

在这里插入图片描述

题:
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
输入格式
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。
1≤N,M≤5。
输出格式
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。

输入:
2 2 1
1 1 2 2
1 2
输出:
1

#include<bits/stdc++.h>
using namespace std;

const int dx[4]={0,0,+1,-1};	//设一个常量数组为x坐标的变化 
const int dy[4]={+1,-1,0,0};	//设一个常量数组为y坐标的变化
int sx,sy,tx,ty;
int a[10][10],b[10][10];
int ans=0;
int n,m,t;

void dfs(int x,int y)
{
	if(x==tx&&y==ty)
	{
		ans++;	//如果等于终点,则方案+1 
		return;	//如果不返回则陷入死循环 
	}
	b[x][y]=1;	//记录已走过 
	for(int i=0;i<4;++i)	
	{
		//枚举四个方向
		//上下左右跟原来的坐标比无非就是+1,-1或者不变 
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(xx<1||yy<1||xx>n||yy>m||b[xx][yy]||a[xx][yy])
		{
			//判断遍历的点是否超出迷宫的范围 
			continue;
		}
		b[xx][yy]=1;
		dfs(xx,yy);		//一直搜索到头了,就会return; 
		b[xx][yy]=0;	//return后回溯,即清空现场,则可进行下一次操作 
	}
}

int main()
{
	cin>>n>>m>>t;
	cin>>sx>>sy>>tx>>ty;	//输入坐标 
	for(int i=1;i<=t;++i)
	{
		int x,y;
		cin>>x>>y;
		a[x][y]=1;	//标记障碍物 
	}
	dfs(sx,sy);
	cout<<ans<<endl;
	return 0;
}

题:
Due to recent rains, water has pooled in various places in Farmer John’s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W’) or dry land (’.’). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.

Given a diagram of Farmer John’s field, determine how many ponds he has.

Input

  • Line 1: Two space-separated integers: N and M

  • Lines 2…N+1: M characters per line representing one row of Farmer John’s field. Each character is either ‘W’ or ‘.’. The characters do not have spaces between them.

Output

  • Line 1: The number of ponds in Farmer John’s field.

Sample Input:

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

Sample Output
3

Hint
OUTPUT DETAILS:
There are three ponds: one in the upper left, one in the lower left,and one along the right side.

题意:
农夫约翰想弄清楚他的田地里形成了多少个池塘。池塘是一组相连的正方形,里面有水,其中一个正方形被认为与八个池塘相邻

思路:这是一道经典的DFS题目,从(0,0)处开始搜索,如果是W的话则把这一位置与之相连的所有的W全部换为 " . " 然后再返回主函数中继续搜索,这样每次在主函数中进行的搜索的次数就是最终的水坑的数量。

#include<stdio.h>
int a,b;
char s[105][105];
void dfs(int x,int y);

void dfs(int x,int y)
{
	s[x][y]='.';
	int dx,dy;
	int i,j;
	for(i=-1;i<=1;++i)
	{
		for(j=-1;j<=1;++j)
		{
			dx=x+i;
			dy=y+j;
			if(dx>=0&&dx<=a&&dy>=0&&dy<=b&&s[dx][dy]=='W')
			dfs(dx,dy);
		}
	}
	return ;
 } 
 
 int main()
 {
	int i,j,n=0;
	scanf("%d%d",&a,&b);
	getchar();
	for(i=0;i<a;++i)
		scanf("%s",s[i]);
	for(i=0;i<a;++i)
	{
		for(j=0;j<b;++j)
		{
			if(s[i][j]=='W')
			{
				dfs(i,j);
				++n;
			}
		}
	}
	printf("%d\n",n);
	return 0;
 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值