1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4 const int maxn=105;
5 int n,m,ans,dir[8][2]={{-1,-1},{-1,1},{1,-1},{1,1},{-1,0},{1,0},{0,-1},{0,1}};
6 char mp[maxn][maxn];bool vis[maxn][maxn];
7 bool is_border(int x,int y){///判断是否越界
8 if(x>=0&&x<n&&y>=0&&y<m)return true;
9 return false;
10 }
11 bool check(int x,int y){///检查点(x,y)周围是否都不是雷
12 for(int i=0;i<8;++i){
13 int nx=x+dir[i][0],ny=y+dir[i][1];
14 if(is_border(nx,ny)&&mp[nx][ny]=='*')return false;
15 }
16 return true;
17 }
18 void dfs(int x,int y){///不必考虑mp[x][y]=='*',因为递归前已都将是雷的排除在外,但是已经访问的要返回,减少递归次数
19 if(vis[x][y])return;///已访问则直接返回
20 vis[x][y]=true;
21 for(int i=0;i<8;++i){
22 int nx=x+dir[i][0],ny=y+dir[i][1];
23 if(is_border(nx,ny)&&!vis[nx][ny]&&mp[nx][ny]=='.'){
24 if(check(nx,ny))dfs(nx,ny);///周围没有雷,则继续dfs扩展能到达的地方
25 else vis[nx][ny]=true;///否则直接标记为T,表示最多只能扩充到当前位置
26 }
27 }
28 }
29 int main(){
30 while(~scanf("%d%d",&n,&m)){
31 memset(vis,false,sizeof(vis));ans=0;
32 for(int i=0;i<n;++i)scanf("%s",mp[i]);
33 for(int i=0;i<n;++i)
34 for(int j=0;j<m;++j)
35 if(!vis[i][j]&&mp[i][j]=='.'&&check(i,j))dfs(i,j),ans++;///先递归扩展空白处
36 for(int i=0;i<n;++i)
37 for(int j=0;j<m;++j)
38 if(!vis[i][j]&&mp[i][j]=='.')ans++;///再将未访问点一下即可
39 printf("%d
",ans);
40 }
41 return 0;
42 }