572 - Oil Deposits

来源:互联网 发布:烟台网络党校 编辑:程序博客网 时间:2024/04/29 23:26

The GeoSurvCompgeologic survey company is responsible for detecting underground oil deposits.GeoSurvComp works with one large rectangular region of land at a time, andcreates a grid that divides the land into numerous square plots. It thenanalyzes each plot separately, using sensing equipment to determine whether ornot the plot contains oil.

A plot containingoil is called a pocket. If two pockets are adjacent, then they are part of thesame oil deposit. Oil deposits can be quite large and may contain numerouspockets. Your job is to determine how many different oil deposits are containedin a grid.

Input 

The input filecontains one or more grids. Each grid begins with a line containing m and n,the number of rows and columns in the grid, separated by a single space.If m = 0 it signals the end of the input; otherwise  and . Followingthis are m lines of n characters each (notcounting the end-of-line characters). Each character corresponds to one plot,and is either `*', representing the absence of oil, or `@', representing an oilpocket.

Output 

For each grid,output the number of distinct oil deposits. Two different pockets are part ofthe same oil deposit if they are adjacent horizontally, vertically, ordiagonally. An oil deposit will not contain more than 100 pockets.

Sample Input 

1 1

*

3 5

*@*@*

**@**

*@*@*

1 8

@@****@*

5 5

****@

*@@*@

*@**@

@@@*@

@@**@

0 0

Sample Output 

0

1

2

2

代码:

#include<iostream>

#include<cstring>

using namespacestd;

 

int m,n;

string str[110];//存储输入的字符串

int idset[110][110];//访问状态标记数组

 

void dfs(int r,intc,int id);//深度优先搜索

 

int main()

{

   while(cin>>m>>n&&m&&n)

    {

        for(int i=0; i<m; i++)

        {

            cin>>str[i];

        }

        memset(idset,0,sizeof(idset));//每组数据必须清空

        int cnt=0;//油田大区域数目

        for(int i=0; i<m; i++)

        {

            for(int j=0; j<n; j++)

            {

               if(str[i][j]=='@'&&idset[i][j]==0)//访问没被访问过的@

                {

                    dfs(i,j,++cnt);

                }

            }

        }

        cout<<cnt<<endl;

    }

    return 0;

}

 

void dfs(int r,intc,int id)

{

if(r<0||r>=m||c<0||c>=n||idset[r][c]!=0||str[r][c]!='@')

//越界或不是@格子或被访问过:直接返回

    {

        return;

    }

    idset[r][c]=id;//标记

    for(int i=-1; i<=1; i++)

    {

        for(int j=-1;j<=1;j++)

        {

            if(i!=0||j!=0)

            {

                dfs(r+i,c+j,id);//递归遍历@的周围8个格子

            }

        }

    }

}

思路:

从每一个’@’格子出发,递归遍历它周围的”@”格子,每次访问完一个”@”格子,就用一个数组将其对应的编号标记,避免重复访问.

 

示意图链接

0 0