acwing \1097. 池塘計數
阿新 • • 發佈:2022-03-05
目錄
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)\)