连通块问题

题目链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1335

方法一:dfs

 1 #include<iostream>
 2 using namespace std;
 3 int n, m, a[110][110], ans=0;
 4 int nex[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
 5 
 6 void dfs(int x, int y, int cnt)//注意考虑这个搜索的结束条件是什么,然而并没有递归出口 
 7 {
 8     a[x][y]=0;
 9     for(int i=0; i<4; i++)
10     {
11         int nx=x+nex[i][0];
12         int ny=y+nex[i][1];
13         if(a[nx][ny]==1)dfs(nx, ny, cnt);
14     }
15 }
16 int main()
17 {
18     cin>>n>>m;
19     for(int i=1; i<=n; i++)
20         for(int j=1; j<=m; j++)
21             cin>>a[i][j];
22     for(int i=1; i<=n; i++)
23         for(int j=1; j<=m; j++)
24             if(a[i][j]==1)
25                 dfs(i, j, ++ans);
26     //测试代码
27 //    for(int i=0; i<n; i++)
28 //    {
29 //        for(int j=0; j<m; j++)cout<<a[i][j]<<" ";
30 //        cout<<endl;
31 //    }        
32     cout<<ans;
33     return 0;
34 } 

方法二:bfs:STL优美展示--笑脸

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 int n, m, a[110][110], ans=0;
 5 int nex[4][2]={{0,-1},{1,0},{0,1},{-1,0}};//四连通遍历坐标 
 6 struct s{
 7     int x;
 8     int y;
 9 }f,t;//结构体变量f,t分别用于存储队列的头和尾 
10 int main()
11 {
12     queue<s>q;//定义结构体类型点队列 
13     cin>>n>>m;
14     for(int i=1; i<=n; i++)
15         for(int j=1; j<=m; j++)
16             cin>>a[i][j];
17                             
18     for(int i=1; i<=n; i++)
19         for(int j=1; j<=m; j++)
20             if(a[i][j]==1)
21             {
22                 a[i][j]=0;//置0防止重复计算 
23                 ++ans;//计数 
24                 t.x=i;  t.y=j;
25                 q.push(t);
26                 while(!q.empty())
27                 {
28                     f=q.front();//获取队列头坐标 
29                     for(int k=0; k<4; k++)
30                         {
31                             int nx=f.x+nex[k][0];//计算下一坐标点x
32                             int ny=f.y+nex[k][1];//计算下一坐标点y
33                             if(a[nx][ny]==1)
34                             {
35                                 a[nx][ny]=0;
36                                 t.x=nx; t.y=ny;
37                                 q.push(t);
38                             }
39                         }
40                     q.pop();
41                 }
42             }
43         //测试代码
44 //    for(int i=0; i<n; i++)
45 //    {
46 //        for(int j=0; j<m; j++)cout<<a[i][j]<<" ";
47 //        cout<<endl;
48 //    }
49     cout<<ans;
50     return 0;
51 }

方法三:并查集???大佬博客传送门

一种题多种写法,深化对算法对理解

【类型题扩展】

四连通》》八连通(什么鬼https://blog.csdn.net/yewei11/article/details/50575593

 

题目一:输入是一个n*m的矩阵,矩阵由0-9的数字构成,0表示海水,数字表示陆地。求四连通的陆地块的数目。

题目二:一个n * m的方格图,一些格子被涂成了黑色,在方格图中被标为1,白色格子标为0。问有多少个四连通的黑色格子连通块。四连通的黑色格子连通块指的是一片由黑色格子组成的区域,其中的每个黑色格子能通过四连通的走法(上下左右),只走黑色格子,到达该联通块中的其它黑色格子。

题目三:同一。被海水包围的陆地称为岛屿,被陆地包围的海水称为湖泊。请除去这些岛屿和湖泊后,求海水和陆地各自的总面积。(商汤科技2018C++ 笔试题)

 

转载于:https://www.cnblogs.com/tflsnoi/p/10169652.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值