1241:Oil Deposits

题目链接: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;
    }
}


你可能感兴趣的:(1241:Oil Deposits)