1. 程式人生 > 其它 >acwing \1097. 池塘計數

acwing \1097. 池塘計數

目錄

題目傳送門

dfs題目描述

農夫約翰有一片 N∗MN∗M 的矩形土地。

最近,由於降雨的原因,部分土地被水淹沒了。

現在用一個字元矩陣來表示他的土地。

每個單元格內,如果包含雨水,則用”W”表示,如果不含雨水,則用”.”表示。

現在,約翰想知道他的土地中形成了多少片池塘。

每組相連的積水單元格集合可以看作是一片池塘。

每個單元格視為與其上、下、左、右、左上、右上、左下、右下八個鄰近單元格相連。

請你輸出共有多少片池塘,即矩陣中共有多少片相連的”W”塊。

輸入格式

第一行包含兩個整數 NN 和 MM。

接下來 NN 行,每行包含 MM 個字元,字元為”W”或”.”,用以表示矩形土地的積水狀況,字元之間沒有空格。

輸出格式

輸出一個整數,表示池塘數目。

資料範圍

1≤N,M≤10001≤N,M≤1000

輸入樣例:

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

演算法求解

分析

st[i][j]表示一個點有沒有被dfs放過過

遍歷整個圖

  • 遇到沒有被訪問過,並且是W的點,計數+1;從該點進行dfs,對其連通的所有W標記訪問過

程式碼

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1010;
char g[N][N]; // 
int n, m;
int res; 
bool st[N][N]; // 標記是不是被訪問過了 
int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};

void dfs(int x, int y)
{
	st[x][y] = true;
	
	for(int i = 0; i < 8; i++)
	{
		int nx = x + dx[i], ny = y + dy[i];
		if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && g[nx][ny] == 'W' && !st[nx][ny])
		{
			dfs(nx, ny);		
		}
	 } 
} 

int main()
{
	scanf("%d%d", &n, &m);
	getchar();
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			scanf("%c", &g[i][j]);	
		}	
		getchar();	
	}	
	
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			if(!st[i][j] && g[i][j] == 'W')
			{
				dfs(i, j);
				res ++;
			}
		}
	}
	cout << res << endl;
	return 0;
} 

時間複雜度

\(O(m*n)\)

參考文章