二维数组区块计数
输入一个只包含0和1的二维数组,上下左右和对角相邻的1组成一个区块,0不形成区块,求数组中的区块个数。
第一行输入两个正整数N和M,N表示数组行数,M表示数组列数。
接下来N行,每行表示数组对应的一行,每行包含M个整数,整数之间用空格隔开。
输出一个整数,表示数组中区块的个数。
$0 \le N,M,N*M \le 10^6$
3 3
0 1 0
1 0 0
1 0 1
2
数组右下角的1单独构成一个区块,其他的3个1对角或上下相邻,构成另一个区块。
解题思路:宽搜/深搜
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| //dfs #include<iostream> #include<algorithm>
using namespace std;
typedef pair<int,int> PII; const int N=1000010; int n,m; int g[N];
void dfs(int x,int y) { g[x*m+y]=0; for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) { int a=x+i,b=y+j; if(a>=0&&a<n&&b>=0&&b<m&&g[a*m+b]) dfs(a,b); } }
int main() { scanf("%d%d",&n,&m); for(int i=0,k=0;i<n;i++) for(int j=0;j<m;j++,k++) scanf("%d",&g[k]); int res=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(g[i*m+j]) { res++; dfs(i,j); } } printf("%d\n",res); return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| //bfs,用STL中的queue #include<iostream> #include<algorithm> #include<queue> using namespace std;
typedef pair<int,int> PII; const int N=1000010;
int n,m; int g[N];
void bfs(int sx,int sy) { queue<PII> q; q.push({sx,sy}); g[sx*m+sy]=0;
while(q.size()) { auto t=q.front(); q.pop(); int x=t.first,y=t.second;
for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) { int a=x+i,b=y+j; if(a>=0&&a<n&&b>=0&&b<m&&g[a*m+b]) { g[a*m+b]=0; q.push({a,b}); } } } } int main() { scanf("%d%d",&n,&m); for(int i=0,k=0;i<n;i++) for(int j=0;j<m;j++,k++) scanf("%d",&g[k]);
int res=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(g[i*m+j]) { res++; bfs(i,j); } printf("%d\n",res); return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| //bfs,用手工写的队列 #include<iostream> #include<algorithm> using namespace std;
typedef pair<int,int> PII; const int N=1000010;
int n,m; int g[N]; PII q[N];
void bfs(int sx,int sy) { int hh=0,tt=0; q[0]={sx,sy}; g[sx*m+sy]=0; while(hh<=tt) { PII t=q[hh++]; int x=t.first,y=t.second; for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) { int a=x+i,b=y+j; if(a>=0&&a<n&&b>=0&&b<m&&g[a*m+b]) { g[a*m+b]=0; q[++tt]={a,b}; } } } } int main() { scanf("%d%d",&n,&m); for(int i=0,k=0;i<n;i++) for(int j=0;j<m;j++,k++) scanf("%d",&g[k]);
int res=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(g[i*m+j]) { res++; bfs(i,j); } printf("%d\n",res); return 0; }
|
- 运行时间:
- 用dfs:1003ms
- 用bfs:
- 用STL中的queue:1932ms
- 用手工写的队列:1036ms