思路:先統計油田的總個數,然後找到圖中第一個油田並由此點開始BFS,得到此點所在油區的油田總數。初始化ans爲1,再將得到的油田總數與油田的總個數相比,若相等則輸出ans。否則用油田總個數減去油田總數,並將結果作爲新的油田總個數。再找第二個未被訪問的油田。直至得到的油田數等於油田總個數(油田總個數在不斷更新)。
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
struct Point
{
int x,y;
} tmp,tmp1;
queue<Point>q;
int m,n;
int vis[105][105];
char str[105][105];
int dx[8] = {-1,1,0,0,-1,-1,1,1};
int dy[8] = {0,0,1,-1,-1,1,-1,1};//上 下 右 左 左上 右上 左下 右下
int BFS(Point p)
{
Point s,t;
int cnt = 1;
while(!q.empty())
{
q.pop();
}
q.push(p);
vis[p.x][p.y] = 1;
while(!q.empty())
{
t = q.front();
q.pop();
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++)
{
s.x = t.x + dx[i];
s.y = t.y + dy[i];
if(!vis[s.x][s.y] && s.x >= 0 && s.x < m && s.y >= 0 && s.y < n && str[s.x][s.y] == '@')
{
cnt++;
vis[s.x][s.y] = vis[t.x][t.y] + 1;
q.push(s);
//printf("%d %d %d\n",s.x,s.y,cnt);
}
}
}
return cnt;
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
if(m == 0)
return 0;
memset(str,'0',sizeof(str));
memset(vis,0,sizeof(vis));
int cnt = 0,ans = 1;
for(int i = 0; i < m; i++)
scanf("%s",str[i]);
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
{
if(str[i][j] == '@')
cnt++;
}
if(cnt == 0)
printf("0\n");
else
{
//printf("%d\n",cnt);
int tot = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
{
if(str[i][j] == '@' && !vis[i][j])
{
tmp.x = i;
tmp.y = j;
tot = BFS(tmp);
if(tot == cnt)
{
printf("%d\n",ans);
break;
}
else
{
ans++;
cnt -= tot;
}
}
}
}
}
return 0;
}