题目链接: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++ 笔试题)