这题一看就是联通块。。。氵
但是肯定有很多新人不会联通块,所以这篇题解就好好讲解一下:
这题联通块的方法就是:
找到所有"#"并挨个搜索,每次搜索就代表找到了一个联通块,应为只要有”#“他所在的地方就一定是一个联通块。然后计数器++,之后呢,搜索所有和他联通的字符,只要联通就代表着他们是一个联通块,最后输出计数器就可以了。。。
是不是很简单???
还有一点要注意的是,这个联通块包括曼哈顿距离为2的点,也就是说:
..*..
.***.
**#**
.***.
..*..
配图一张~:
所有与#联通的都要算上,所以方向数组因该写成这样:
const int dx[12]={1,-1,0,0,2,-2,0,0,1,-1,1,-1};
const int dy[12]={0,0,1,-1,0,0,2,-2,-1,1,1,-1};
好了,下面贴上你们最喜欢的代码了如果有不懂的见注释
C++ Code:
#include<bits/stdc++.h>
using namespace std;
const int dx[12]={1,-1,0,0,2,-2,0,0,1,-1,1,-1};
const int dy[12]={0,0,1,-1,0,0,2,-2,-1,1,1,-1};//方向数组
int n,m,vis[101][101],ans;
char g[101][101];//注意数组大小!!
void bfs(int x,int y)
{
ans++;//每次计数器++
queue<int> q1,q2;
q1.push(x);q2.push(y);//入队
while(!q1.empty())//如果队不为空
{
int nowx=q1.front(),nowy=q2.front();
q1.pop(),q2.pop();//取出队头然后pop掉
for(int i=0;i<12;i++)//12个位置搜索
{
int tx=nowx+dx[i];
int ty=nowy+dy[i];
if(tx>=1 and tx<=n and ty>=1 and ty<=m and g[tx][ty]=='#' and !vis[tx][ty])
{
vis[tx][ty]=1;
q1.push(tx);
q2.push(ty);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>g[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(g[i][j]=='#' and !vis[i][j])
bfs(i,j);//如果是#就搜索一下~
cout<<ans;//输出答案
while(true) printf("放抄袭!!");
return 0;
}
好了,这就是这题的解法。没什么好说的了。