所需知识:flood fill,dfs,bfs
思路:
先遍历一遍地图,用一个数组存地图上每个点九宫格内有多少个炸弹,若碰到炸弹,则将炸弹标记(vis[i][j]=-1),然后将地图中vis为0的地方dfs,若其九宫格内还有vis为0的点,则继续dfs下去,直到九宫格内没有vis为0的点了,然后将res(存答案)+1;接着将整个地图中vis为0的点全部遍历完,之后遍历地图中还未遍历到的点(附近有炸弹,未被第一次遍历标记),找到一个则res++;
dfs(int i,int j):将地图中(i,j)的点标记,若该点附近没有炸弹,则将九宫格内整块区域全部标记,否则,直接返回;
C++代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char Map[305][305];
int vis[305][305];
int T;
int N;
int res;
void dfs(int i,int j){
int t=vis[i][j];
vis[i][j]=-1;
if(t)return;
else{
for (int x = i-1; x <= i+1; x ++ )
for (int y = j-1; y <= j+1; y ++ )
if(x>=1&&x<=N&&y>=1&&y<=N&&vis[x][y]!=-1)
dfs(x,y);
}
}
int main()
{
cin>>T;
for (int i = 1; i <= T; i ++ ){
res=0;
cin>>N;
for (int i = 1; i <= N; i ++ )
for (int j = 1; j <= N; j ++ )
cin>>Map[i][j];
for (int i = 1; i <= N; i ++ )
for (int j = 1; j <= N; j ++ ){
if(Map[i][j]=='*')
vis[i][j]=-1;
else{
vis[i][j]=0;
for (int x = i-1; x <= i+1; x ++ )
for (int y = j-1; y <= j+1; y ++ )
if(x>=1&&x<=N&&y>=1&&y<=N&&Map[x][y]=='*')
vis[i][j]++;
}
}
for (int i = 1; i <= N; i ++ )
for (int j = 1; j <= N; j ++ ){
if(vis[i][j]==0)
{
dfs(i,j);
res++;
}
}
for (int i = 1; i <= N; i ++ )
for (int j = 1; j <= N; j ++ ){
if(vis[i][j]!=-1)
res++;
}
printf("Case #%d: %d\n",i,res);
}
return 0;
}