地址 http://poj.org/problem?id=2386ios
《挑戰程序設計競賽》習題算法
題目描述
Descriptionide
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.spa
Given a diagram of Farmer John’s field, determine how many ponds he has.設計
Inputcode
Line 1: Two space-separated integers: N and Morm
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.
Outputblog
Line 1: The number of ponds in Farmer John’s field.ip
樣例ci
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
算法1
將相同的水坑算在一塊兒 並查集
C++ 代碼
#include <iostream> #include <set> using namespace std; #define MAX_NUM 110 int N, M; char field[MAX_NUM+10][MAX_NUM + 10]; int fa[MAX_NUM*MAX_NUM]; //char field[10][12] = { // {'W','.','.','.','.','.','.','.','.','W','W','.'}, // {'.','W','W','W','.','.','.','.','.','W','W','W'}, // {'.','.','.','.','W','W','.','.','.','W','W','.'}, // {'.','.','.','.','.','.','.','.','.','W','W','.'}, // {'.','.','.','.','.','.','.','.','.','W','.','.'}, // {'.','.','W','.','.','.','.','.','.','W','.','.'}, // {'.','W','.','W','.','.','.','.','.','W','W','.'}, // {'W','.','W','.','W','.','.','.','.','.','W','.'}, // {'.','W','.','W','.','.','.','.','.','.','W','.'}, // {'.','.','W','.','.','.','.','.','.','.','W','.'} //}; //=============================================== // union find void init(int n) { for(int i=1;i<=n;i++) fa[i]=i; } int get(int x) { return fa[x]==x?x:fa[x]=get(fa[x]);//路徑壓縮,防止鏈式結構 } void merge(int x,int y) { fa[get(x)]=get(y); } //=========================================================== void Check(int x,int y) { //上 int xcopy = x - 1; if (xcopy >= 0 && x < N) { for (int add = -1; add <= 1; add++) { int ycopy = y + add; if (ycopy >= 0 && ycopy < M && field[xcopy][ycopy] == 'W') { int idx = x * M + y; int anotherIdx = xcopy * M + ycopy; merge(idx, anotherIdx); } } } //中 xcopy = x; if (xcopy >= 0 && x < N) { for (int add = -1; add <= 1; add++) { if (add == 0) continue; int ycopy = y + add; if (ycopy >= 0 && ycopy < M && field[xcopy][ycopy] == 'W') { int idx = x * M + y; int anotherIdx = xcopy * M + ycopy; merge(idx, anotherIdx); } } } //下 xcopy = x + 1; if (xcopy >= 0 && x < N) { for (int add = -1; add <= 1; add++) { int ycopy = y + add; if (ycopy >= 0 && ycopy < M && field[xcopy][ycopy] == 'W') { int idx = x * M + y; int anotherIdx = xcopy * M + ycopy; merge(idx, anotherIdx); } } } } int main() { cin >> N >> M; //N = 10; M = 12; init(MAX_NUM*MAX_NUM); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cin >> field[i][j]; if (field[i][j] == 'W') { //檢查上下左右八個方向是否有坑 Check(i,j); } } } set<int> s; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (field[i][j] == 'W') { int idx = i * M + j; //cout << "fa["<<idx << "] = "<< fa[idx] << endl; s.insert(get(idx)); } } } cout << s.size() << endl; return 0; } 做者:defddr 連接:https://www.acwing.com/solution/acwing/content/3674/ 來源:AcWing 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
算法2
DFS 遍歷 將座標連續的坑換成. 計數+1
C++ 代碼
#include <iostream> using namespace std; int N, M; int unitCount = 0; #define MAX_NUM 110 char field[MAX_NUM + 10][MAX_NUM + 10]; //char field[10][12] = { // {'W','.','.','.','.','.','.','.','.','W','W','.'}, // {'.','W','W','W','.','.','.','.','.','W','W','W'}, // {'.','.','.','.','W','W','.','W','W','W','W','.'}, // {'.','.','.','.','.','.','.','.','.','W','W','.'}, // {'.','.','.','.','.','.','.','.','.','W','.','.'}, // {'.','.','W','.','.','.','.','.','.','W','.','.'}, // {'.','W','.','W','.','.','.','.','.','W','W','.'}, // {'W','.','W','.','W','.','.','.','.','.','W','.'}, // {'.','W','.','W','.','.','.','.','.','.','W','.'}, // {'.','.','W','.','.','.','.','.','.','.','W','.'} //}; void Dfs(int x, int y) { //終止條件 if (x < 0 || x >= N || y < 0 || y >= M || field[x][y] == '.') return; field[x][y] = '.'; Dfs(x + 1, y - 1); Dfs(x + 1,y); Dfs(x + 1, y + 1); Dfs(x , y-1); Dfs(x , y + 1); Dfs(x -1, y-1); Dfs(x - 1, y); Dfs(x - 1, y +1); } int main() { cin >> N >> M; //N = 10; M = 12; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cin >> field[i][j]; } } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (field[i][j] == 'W'){ unitCount++; Dfs(i,j); } } } cout << unitCount << endl; return 0; }