acm:屁屁上的巴掌
涉及算法:深度搜索
题目:
题目描述 小新是个调皮的孩子,他总是会把衣服搞脏,他的妈妈美伢非常的生气,于是在《和妈妈的约定条款》加上了第三百七十七条:小新衣服上每有一块污渍妈妈就会打小新的小屁屁一下作为惩罚。我们规定如果两个污渍相邻(直接相邻的上下左右、左上、左下,右上、右下都算相邻)那么它们就算是一块污渍。现在小新又把衣服搞脏了,请你帮他算一算他的屁股上会挨几巴掌? 输入 输入将会包含多组测试数据,每组测试数据将会以m和n开头,表示将会用m行n列的网格代表小新的衣服,如果m=0输入结束;1 <= m <= 100 并且1 <= n <= 100.接下来是m行n列的网格,网格中’@’代表污渍,’*’代表没有污渍。 输出 对于每组数据,请输出小新屁股挨到的巴掌的数量。
样例输入
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
样例输出
0 1 2 2
大致搜索步骤:搜到一个是污渍后,标记上“已搜过”,紧接着搜它的周围,重复此步骤。遇到*后就停止,回到上一层。走到不能搜的点后跳过,搜完后也回到上一层。
注意:搜索前要判断该点是否越界,是否已搜过。
代码:
#include<stdio.h> #include<string.h> int color(int x, int y); char map[101][101]; int res[101][101]; int direct[4]={-1,0,1}; int m,n; int main(){ int flag; int i,j; while(scanf("%d%d",&m,&n)!=EOF){ getchar(); memset(map,0,sizeof(map)); memset(res,0,sizeof(res)); flag=0; if (m==0) break; for(i=0;i<m;i++){ gets(map[i]); } for(i=0;i<m;i++) for(j=0;j<n;j++){ if (res[i][j]!=0) continue; else{ flag+=color(i,j); } } printf("%d\n",flag); } return 0; } int color(int x, int y){ int i,j; if(map[x][y]=='*') return 0; else{ res[x][y]=1; for(i=0;i<3;i++) for(j=0;j<3;j++){ if(x+direct[i]>=0 && x+direct[i]<m && y+direct[j]>=0 && y+direct[j]<n && (!res[x+direct[i]][y+direct[j]])){//注意逻辑取反!,而不是用位取反~ color(x+direct[i],y+direct[j]);//上下左右检测的便捷写法,每种情况都要判断边界,判断是否已读 } } } return 1; }