纯粹自己对完成的题,有一点点小惊喜,嘿嘿。DFS的经典算法,题意大致是先输入数字N,M作为长度和宽度,再输入一个含有字符W和 . 的N*M的字符数组;说W代表水,. 表示干旱地,水聚集起来可以形成水塘让我们统计该字符数组所代表的地区中水塘的个数并输出;
虽然算法是dfs的基本算法但是这道题坑的地方太多了,博主表示提交了好几次要不就是超时要么就runtime error,最后干脆重写了一份提交结果AC了,哎,现在都不知道开始错哪了。
最开始想用广搜bfs最后发现因为每个点都必遍历到,使用bfs算法不好设置条件,那就运用深度搜索吧,因为要统计水塘的数量,运用循环从坐标为(0,0)开始遍历,如果正在遍历的点是W并且还并未被标记,那么说明该点处及其周围必定存在一个水塘,那么count加一,同时调用dfs算法把该点所在处聚集的W的全部找出来并且标记;这样该水塘的所有W都将不会再被访问到了,就这样循环一直到(n,m),那么累加的count即是水塘的个数;至于dfs算法,就是运用递归把符合条件且连通的点全部遍历上,详细解释可以在维基百科上找到,这里就不介绍了,嘿嘿。时间复杂性应该是o(n2);
这里需要说明几个比较坑的地方,1:"W"是大写,不然老是WA,2:输入时每个字符间是没有空格的 3:单个W也算作一个水塘,还有就是两个对角相邻的W也算作一个水塘的一部分,好了,现在上代码
Accepted 492K 63MS
C++
#include<iostream>
#define maxn 100
using namespace std;
struct poi //构建一个结构体,也可以用两个数组代替
{
char item; //字符,代表水还是干旱
bool vis; //标记,记得要初始化为零
}lake[maxn][maxn]; //申请一个结构体数组
int n,m,count;
int px[8]={-1,1,0,0,1,-1,1,-1};
int py[8]={0,0,-1,1,1,-1,-1,1};
void dfs(int x,int y)
{
int k,dx,dy;
lake[x][y].vis=true;
for(k=0;k<8;k++) //因为要考虑对角相邻,所以一共可能有八个分支
{
dx=x+px[k];
dy=y+py[k];
if((dx<0)||(dy<0)||(dx>=n)||(dy>=m) //判断条件
||(lake[dx][dy].vis==true)||(lake[dx][dy].item=='.'))
continue;
dfs(dx,dy);
}
return;
}
int main()
{
count=0;
int i,j;
cin>>n>>m;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
cin>>lake[i][j].item;
lake[i][j].vis=false; //初始化
}
for(i=0;i<n;i++)
for(j=0;j<m;j++) //循环遍历
if((lake[i][j].vis==false)&&(lake[i][j].item=='W')) //记得输入的是大写
{
dfs(i,j);
count++;
}
cout<<count<<endl;
return 0;
}