家 族 家族 家族
题目链接:jzoj 1985
题目大意
有一个只有空格、星号(
∗
*
∗)和小写字母的图,问有多少堆连在一起的小写字母。
(连在一起是有连在一起的在上下左右中的至少一个方向)
样例输入
4
*zlw**pxh
l*zlwk*hx*
w*tyy**yyy
zzl
样例输出
3
数据范围
对于10%的数据, n<=1
对于30%的数据, n<=10
对于100% 的数据, n<=100 每一行最多不超过 200 个字符
思路
这道题我们用
d
f
s
dfs
dfs来做。
枚举每一个点,如果没到过而且是小写字母就堆数加一,并且
d
f
s
dfs
dfs,找出那一堆小写字母,全部标记。
最后,我们只要输出堆数就可以了。
代码
#include<cstdio>
#include<cstring>
using namespace std;
int n,l[301],ans,x[4]={0,1,0,-1},y[4]={1,0,-1,0};
bool in[301][301];
char c;
void dfs(int xx,int yy)//dfs
{
in[xx][yy]=1;//标记
for (int i=0;i<4;i++)//上下左右四个方向
if (!in[xx+x[i]][yy+y[i]])//没到过且是小写字母
{
in[xx+x[i]][yy+y[i]]=1;//标记
dfs(xx+x[i],yy+y[i]);//dfs
}
}
int main()
{
// freopen("family.in","r",stdin);
// freopen("family.out","w",stdout);
memset(in,1,sizeof(in));//初始化
scanf("%d",&n);//读入
c=getchar();//读入
for (int i=1;i<=n;i++)
{
while (!(c=='*'||c==' '||(c>='a'&&c<='z'))) c=getchar();//读入
while (c=='*'||c==' '||(c>='a'&&c<='z'))
{
l[i]++;//长度增加
if (c!='*'&&c!=' '&&c>='a'&&c<='z') in[i][l[i]]=0;//标记
c=getchar();//读入
}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=l[i];j++)
if (!in[i][j])//没有到过且是小写字母
{
ans++;//堆数增加
dfs(i,j);//dfs
}
printf("%d",ans);//输出
// fclose(stdin);
// fclose(stdout);
return 0;
}