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;
}

 

posted @ 2018-12-06 23:55  omegablank  阅读(488)  评论(0编辑  收藏  举报