Lake Counting(深度優先演算法)
這個題的模板 也可以AC 另兩個題 ,程式碼意思都是差不多的
Red and Black(找黑磚的個數)點選開啟連結
Oil Deposits(計算油田的個數)點選開啟連結
Description
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.
大致題意
有一個大小為N*M的園子,雨後積了很多水。八連通的積水被認為是在一起的。請求出園子裡共有多少個水窪?(八連通是指下圖中相對.的8 部分)
www
w.w
www
從任意的'W'開始,不停地把鄰接的部分用'.'代替,一次DFS(深度優先遍歷)遍歷後,與初始的這個 W 所連線的所有 'W' 都會被替換成 '.',因此直到圖中沒有 'W'為止,總共進行 DFS 的次數即為積水的次數。
程式碼如下:
第一種方法;
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char a[1001][1001];
int n,m;
void DFS(int x,int y)
{
int i,j,b,c;
for(i=-1;i<=1;i++){
for(j=-1;j<=1;j++){
b=i+x;//代表了八個方向 (i-1,j-1) (i-1,j) (i-1,j+1) (i,j-1)
c=y+j;// (i,j+1) (i+1,j-1) (i+1,j) (i+1,j+1)
if(b>=0&&b<n&&y>=0&&y<m&&a[b][c]=='W')
{
a[b][c]='.';//如果改點是 ’W' 的話 就另 該點是 '.' 以後也不訪問他
DFS(b,c);// 去搜索該點
}
}
}
}
int main()
{
int i,j,flag=0;
while(scanf("%d %d",&n,&m)!=EOF){
memset(a,'0',sizeof(a));
flag=0;
for(i=0;i<=n-1;i++)
scanf("%s",a[i]);
for(i=0;i<=n-1;i++){
for(j=0;j<=m-1;j++){
if(a[i][j]=='W'){
flag++;//遇見一個水窪 就加加
DFS(i,j);//去搜索這一點的八個方向
}
}
}
printf("%d\n",flag);
}
}
第二種方法:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char a[1001][1001];
int n,m;
void DFS(int i,int j)
{
if(i>=0&&i<n&&j>=0&&j<m&&a[i][j]=='W'){
a[i][j]='.';//相比於第一種,這裡用了八個 DFS,第一種用了迴圈來表示八個方向
DFS(i-1,j-1);
DFS(i-1,j);
DFS(i-1,j+1);
DFS(i,j-1);
DFS(i,j+1);
DFS(i+1,j-1);
DFS(i+1,j);
DFS(i+1,j+1);
}
}
int main()
{
int i,j,flag=0;
while(scanf("%d %d",&n,&m)!=EOF){
memset(a,'0',sizeof(a));
flag=0;
for(i=0;i<=n-1;i++)
scanf("%s",a[i]);
for(i=0;i<=n-1;i++){
for(j=0;j<=m-1;j++){
if(a[i][j]=='W'){
flag++;
DFS(i,j);
}
}
}
printf("%d\n",flag);
}
}