(2021OJ更新)
B 图像分割增强版
Time Limit:1000MS Memory Limit:65535K
题型: 编程题 语言: 无限制
描述
给定一个n行m列的二值图像,0为背景,1为前景物,请计算该图像中有多少块区域块(由连接的1构成),并输出
最大的区域块的像点数。
同一个区域块中的点要么是连接的,要么是存在包围关系。
判断两个区域是否连接采用四邻域判定,即一点仅与它的上下左右四个点相连;
判断两个区域是否存在包含关系即一个区域被另一个区域完全包围,如下所示,中间的两个1被外面的16个1完全包围(中间的两个1不
存在通往外界的四邻域通路)
00000000
00111110
00100001
00101101
00100001
00111110
00000000
存在包围关系的两个区域属于同一个区域块
输入格式
第一行两个正整数,n和m(n,m<=100)
此后n行,每行m个0或1
输出格式
输出区域块数和最大区域块像点数,数字中间以一个空隔分隔
输入样例
6 8
01111110
01000010
01011010
01000010
01111110
00000001
输出样例
2 20
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char a[102][102],a1[102][102];
int vis[102][102];
int sum=0;
int n,m,fenliang;
void dfs(int i,int j)
{
if(vis[i][j])return ;
if(a[i][j]=='1')fenliang++;
vis[i][j]=1;
dfs(i+1,j);
dfs(i,j+1);
dfs(i-1,j);
dfs(i,j-1);
return ;
}
void dfs0(int i,int j)//先把外围全部给他标记掉,分开一块一块
{
if(i>n+1||j>m+1||i<0||j<0)return;
if(a[i][j]=='0'&&vis[i][j]==0)
{
vis[i][j]=1;
dfs0(i+1,j);
dfs0(i,j+1);
dfs0(i-1,j);
dfs0(i,j-1);
}
return ;
}
int main()
{
int maxx=-1e9;
cin>>n>>m;
memset(a,'0',sizeof a);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
a[i][m+1]='0';
}
dfs0(0,0);//外圈
// for(int i=0;i<=n+1;i++)
// {for(int j=0;j<=m+1;j++)//
// {cout<<vis[i][j];
// }
// cout<<endl;}//
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='1'&&vis[i][j]==0)
{
fenliang=0;
sum++;
dfs(i,j);
maxx=max(maxx,fenliang);
}
}
}
cout<<sum<<' '<<maxx;
return ;