<<The algorithm is beautiful>——(7)——DFS classic question (1): number of puddles

content

Problem Description

problem analysis

Grading over


Problem Description

There is a garden of size N×MN×MN\times MN×M, and water has accumulated after the rain. Eight connected ponds are considered to be connected together. How many puddles are there in the garden? Eight-connection refers to the ∗ part relative to W in the figure below, 'W' means stagnant water, and '*' means no stagnant water.

∗∗∗
∗W∗
∗∗∗

input sample

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

problem analysis

If there is water in this red place, first take it as the center, look for it, and continue to look down with the new one as the center.

But there will be a problem in this way, that is, it will go back, and it will fall into an infinite loop. How can we prevent such a thing from happening? Let's think about it first, let's leave a suspense here

Continue to move forward and find that there is no water in front of it. It starts to find out whether there is water in another direction. After finding no, it will retreat to the previous layer and continue to find out if there is water in other directions. It does not continue to retreat until Retreat to the eight directions of the first stagnant water, and you are done.

ok, we started to think about how to avoid it going back into the situation bag of an infinite loop?

As long as there is stagnant water where we go, we will drain the stagnant water after walking and let it dry, which is the example given in the above example. into '*', so that after the traversal is completed, he will become '*' and it will end, avoiding an infinite loop.

This question is very classic. This kind of thinking can be said to be tried and tested in deep search, so we can use this as a template for example questions, memorize it, and encounter similar questions, such as mazes, islands, etc., we can directly set the template.

Ado,

Grading over

#include<iostream>
#include<cstring>
using namespace std;
int cnts;
//n是行,m是列
int n, m;
void dfs(string* a, int i, int j)
{
	//a[i][j] = '.';
	//if (i > 0 && a[i - 1][j] == 'W')dfs(a, i - 1, j);//上方
	//if (i <n-1&& a[i + 1][j] == 'W')dfs(a, i + 1, j);//下方
	//if (j > 0 && a[i][j - 1] == 'W')dfs(a, i, j - 1);//左
	//if (j < m - 1 && a[i][j + 1] == 'W')dfs(a, i, j + 1);//右
	//.....
	a[i][j] = '.';
	for (int k = -1; k < 2; k++)//-1,0,1
	{
		for (int l = -1; l < 2; l++)//-1,0,1
		{
			if (k == 0 && l == 0)continue;
			if (i + k >= 0 && i + k <= n - 1 && j + l >= 0 && j + 1 <= m - 1)
			{
				if (a[i + k][j + l] == 'W')
				{
					dfs(a, i + k, j + l);
				}
			}
		}
	}
}
int main()
{
	cin >> n >> m;
	string* a=new string[n];
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (a[i][j] == 'W')
			{
				dfs(a,i,j);
				cnts++;
			}
		}
	}
	cout << cnts << endl;
	return 0;
}

Let's go back to this topic again:

 We use a double for loop to traverse this two-dimensional array. First, we find the 'W' of the first group and DFS traversal. When encountering 'W', we continue to go down until all the 'W' of the first group become '.', just return, then the first puddle is traversed, cnts is added by 1, and the for loop continues to find the position of the next set of 'W', as shown in 2 and 3 in the above figure. Repeat the operation of 1 until Traverse all 'W' to '.' so that the for loop ends. The number of cnts at this time is the number of puddles.

Here we think about a question, can we backtrack here? The answer is definitely no, because when we traverse and change it to '.' and then backtrack it becomes 'W', the back and forth cannot be counted at all, so the use of backtracking should be carried out according to each topic. Flexible judgment.

Guess you like

Origin blog.csdn.net/m0_58367586/article/details/123937530