1.题目描述:
黑白图像
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte
Total Submit:282 Accepted:82
Total Submit:282 Accepted:82
Description
输入一个n×n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连块的个数。如果两个黑格子有公共边或者公共顶点,就说它们属于同一个八连块。如下图所示的图形有3个八连块。
Input
第1行输入一个正整数n(n≤700),此后输入n行,每行是由n个0或1组成的字符串。
Output
在输入黑白图像中,八连块的个数
Sample Input
6
100100
001010
000000
110000
111000
010100
Sample Output
3
Source
刘汝佳《算法竞赛入门经典》
2.思路分析:
首先我们可以看见这个问题属于有关图的递归问题,对于每一个黑格我们都有类似的操作:
1.首先看这个含1的数据是否被访问过,判断是否被访问过可以考虑用一个等大的二维数组对每一个数据进行鉴别;
2.该数据周围的八个数据是否为1.如果是将其鉴别变量变为1,后面不再考虑。
3:代码展示:
1 #include<stdio.h> 2 #include<memory.h> 3 const int MAXN=1000; 4 void dfs(int i,int j); 5 int vis[MAXN][MAXN],mat[MAXN][MAXN]; 6 char S[MAXN]; 7 int main() 8 { 9 int n; 10 //dfs[1][1]; 11 while(scanf("%d",&n)!=EOF) 12 { 13 int count =0,num=1; 14 memset(vis,0,sizeof(vis)); 15 memset(mat,0,sizeof(mat)); 16 for(int i=1;i<=n;i++)//首先输入数据,并注意边缘问题 17 { 18 scanf("%s",S); 19 for(int j=0;j<n;j++) 20 mat[i][j+1]=S[j]-'0'; 21 memset(S,'\0',sizeof(S)); 22 } 23 for(int i=1;i<=n;i++) 24 for(int j=1;j<=n;j++) 25 { 26 if(mat[i][j]&&(!vis[i][j])) 27 { 28 count++; 29 dfs(i,j); 30 } 31 } 32 printf("%d\n",count); 33 } 34 return 0; 35 } 36 void dfs(int i,int j) 37 { 38 if(!mat[i][j]||vis[i][j]) return ; 39 vis[i][j]=1; 40 dfs(i-1,j-1); dfs(i-1,j);dfs(i-1,j+1); 41 dfs(i,j-1); dfs(i,j+1); 42 dfs(i+1,j-1);dfs(i+1,j);dfs(i+1,j+1); 43 44 }
总结:
1.BFS与DFS问题都需要注意边界问题,不能超出数据所规定的范围。本题是考虑在边界上加一圈隐形白格。
2.递归调用会把局部变量(i,j,i-1,j-1·····)压入帧栈中,如果图像太大,则有溢出危险。