在刘汝佳的《算法艺术》第二版上看到了这道题,一早上起来拿这道题热身,AC过。
思路:
八连块,那么就是从(-1,0,1),(-1,0,1)上选取欧几里得集合后再去掉(0,0)这一点。
在找到一块‘@'后,从八个方向进行搜索,并且如果找到一块,进行标记,之后不再进行。
tips:
1.注意memset和int cnt=0的位置,确保每一次开始前都是新的。
2.没有用1和0进行标记,而是用cnt来作为每一次开始新的循环,这样就免掉了计数部分。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
char map[maxn][maxn];
int vis[maxn][maxn];
int n,m;
void dfs(int x,int y,int cnt)
{
if(x<0||x>n-1||y<0||y>m-1||map[x][y]=='*'||vis[x][y]>0) //都是不能再继续下去的标志
return;
vis[x][y]=cnt;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
{
if(!(i==0&&j==0)) dfs(x+i,y+j,cnt);
}
}
int main(void)
{
int i,j,k;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
int cnt=0;
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++) cin>>map[i];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(map[i][j]=='@'&&vis[i][j]==0)
dfs(i,j,++cnt);
}
cout<<cnt<<endl;
}
}