题目链接 :http://poj.org/problem?id=2386
题目大意:计算出一共有多少块水洼
解决方法:从任意的w开始,不停地把邻接的部分用 ‘ . ’ 代替,一次 dfs 之后与这个w连接的所有w就都被替换成了 ‘ . ’ ,因此知道图中不再存在W为止,总共进行的 dfs 的次数就是答案了。
复杂度:由于8个方向对应了8种状态转移,每个格子作为dfs参数至多被调用一次,所以O(8*N*M)=O(N*M);
这里我使用了从文件读取数组,当然输入根据情况而定。
#include<iostream>
#include<fstream>
#include<cstdio>
using namespace std;
const int MAX_N = 101;
const int MAX_M = 101;
int N,M;
char a[MAX_N][MAX_M];
void dfs(int x,int y){
int nx,ny;
a[x][y]='.';
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){// 定义方向
nx=x+i; //nx,ny为现在的坐标
ny=y+j;
if((nx>=0)&&(nx<N)&&(ny>=0)&&(ny<M)&&(a[nx][ny]=='W'))
dfs(nx,ny);
}
}
return;
}
void solve(){
int count=0;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(a[i][j]=='W'){
dfs(i,j);
count++;
}
}
}
cout<<count;
}
int main(){
int i,j;
cin>>N>>M;
FILE*filename=fopen("lake_counting.txt","r");
if (!filename){
cout<<"open file failed"<<endl;
}
for(i=0;i<N;i++){
for(j=0;j<M;j++){
fscanf(filename,"%c",&a[i][j]);
}
fscanf(filename,"\n"); //从filename所指的文件中读取一个换行符
}
fclose(filename);
solve();
return 0;
}
这是不读取文件的版本
#include<iostream>
#include<fstream>
#include<cstdio>
using namespace std;
const int MAX_N = 101;
const int MAX_M = 101;
int N,M;
char a[MAX_N][MAX_M];
void dfs(int x,int y){
int nx,ny;
a[x][y]='.';
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){// 定义方向
nx=x+i; //nx,ny为现在的坐标
ny=y+j;
if((nx>=0)&&(nx<N)&&(ny>=0)&&(ny<M)&&(a[nx][ny]=='W'))
dfs(nx,ny);
}
}
return;
}
void solve(){
int count=0;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(a[i][j]=='W'){
dfs(i,j);
count++;
}
}
}
cout<<count;
}
int main(){
int i,j;
cin>>N;
cin>>M;
for(i=0;i<N;i++){
for(j=0;j<M;j++){
cin>>a[i][j];
}
}
solve();
return 0;
}