题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241
方法:dfs
思路:一看题觉得搜索倒是不难,难就难在怎样判断连通图。后查阅资料,发现了一种与dfs巧妙结合的神奇方法,真是拜服啊!首先还是按照一般原则对地图进行深搜,不同的是,我们的dfs函数不返回任何值,其作用就是对原图进行修改。修改的方法是,以一个点为基准,向他周围八个方向辐射,如果这些点中有油田,则标记这些油田为无油田,因为这些地方虽然有油田,但是他和我们的基准点是连在一起的,在拓扑结构上来说他们就是一个油田,完全可以用基准点来代替!这样的话,我们在主程序中,遍历地图,凡是有油田的地方,就进行dfs,dfs结束后,该油田会把自己所有联通的油田全都干掉,这样有多少单个的油田,那么就有多少成片的油田!
难点:连通图的判定。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX = 110;
char maze[MAX][MAX];
int mark[MAX][MAX];
int n,m;
int counter = 0;
int dir[8][2]={1,0,0,1,-1,0,0,-1,1,1,-1,1,1,-1,-1,-1};
void dfs(int x,int y,int step)
{
int nextx,nexty,nextstep;
for(int i = 0;i < 8;i++)
{
nextx = x+dir[i][0];
nexty = y+dir[i][1];
nextstep = step+1;
if(nextx >= n || nextx < 0 || nexty >= m || nexty < 0)
continue;
if(maze[nextx][nexty] == '@')
{
maze[nextx][nexty] = '*';
dfs(nextx,nexty,nextstep);
//maze[nextx][nexty] = '@';
}
}
}
int main()
{
while(cin>>n>>m)
{
if(n == 0&& m == 0) break;
int ans = 0;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
cin>>maze[i][j];
}
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
if(maze[i][j] == '@')
{
maze[i][j] = '*';
ans++;
dfs(i,j,0);
}
}
}
cout<<ans<<endl;
}
}