題目鏈接: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++ 筆試題)