poj2386Lake Counting(DFS算法)

纯粹自己对完成的题,有一点点小惊喜,嘿嘿。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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值