<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">题目描述</span>
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">题目描述</span>
输入一个n*n的黑边图像(1表示黑色,0表示白色)任务是统计其中八连块的个数。八连块:如果两个黑色格子有公共边或者是公共顶点,则这两个格子属于一个八连块。
输入
n*n的黑白图像。
输出
八连块的个数
样例输入
6
及如图图像
样例输出
3
解题思路
用递归的思想,从每一个黑色的格子开始,递归访问他周围的8个格子 直到碰到白格子停止。
注意: 二维数组a[i][j]
代码
#include<cstdio>
using namespace std;
int mat[100][100]={};//地图
int vist[100][100]={};//记录访问过的格子
void dfs(int x,int y)
{
if(!mat[x][y]||vist[x][y])return;//这个格子是白色的或者曾经访问过。
vist[x][y]=1; //标记为已访问, 这里还可以取消此数组,直接将mat[x][y]=0;作为已访问的标志
//递归访问周围的8个格子
dfs(x-1,y-1); dfs(x-1,y); dfs(x-1,y+1); //这里考虑到有可能会越界,于是在主函数中进行一圈虚拟白格子
dfs(x,y-1); dfs(x,y+1);
dfs(x+1,y-1); dfs(x+1,y); dfs(x+1,y+1);
//还可以写成
// int dir[]={1,-1,0,0};
// for (int i=0;i<4;++i)
// {
// for(int j=0;j<4;++j)
// {
// if(i==0&&j==0)continue;//跳过寻找自身,进行优化
// dfs(x+dir[i],y+dir[j]);
//
// }
// }
}
int main()
{
char s[100];
int i,j;
int n;
int ans =0;
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%s",s);
for(j=0;j<n;++j)//注意从i+1和j+1开始,目的是虚拟一圈白格子做围墙
{
mat[i+1][j+1] = s[j]-'0';//因为是char型数组,所以要减去0的ascii码
}
}
for(i=1;i<n;++i)
{
for(j=1;j<n;++j)
{
if(mat[j][i]&&!vist[j][i])
{
ans++;
dfs(j,i);//传入j,i 还是j,i无所谓,因为反正是周围八个格子
}
}
}
printf("%d",ans);
return 0;
}