HDU--OJ--1241 Oil Deposits

来源:互联网 发布:mac mini安装win7教程 编辑:程序博客网 时间:2024/06/04 18:57

点击打开链接




Oil Deposits

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3427    Accepted Submission(s): 1954


Problem Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
 

Input
The input file contains 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 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
 

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

Sample Input
1 1*3 5*@*@***@***@*@*1 8@@****@*5 5 ****@*@@*@*@**@@@@*@@@**@0 0
 

Sample Output
0122



题解:


有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索。它们最终都会到达所有连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。  

深度优先搜索:
下面图中的数字显示了深度优先搜索顶点被访问的顺序。

为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
(1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
(2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
(3) 如果不能执行规则1和规则2,就完成了整个搜索过程。

广度优先搜索:
在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区域。它是用队列来实现的。
下面图中的数字显示了广度优先搜索顶点被访问的顺序。

实现广度优先搜索,也要遵守三个规则:
(1) 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
(2) 如果因为已经没有未访问顶点而不能执行规则1时,那么从队列头取一个顶点,并使其成为当前顶点。
(3) 如果因为队列为空而不能执行规则2,则搜索结束。


AC代码:


DFS:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int MAX = 1e2 + 10;typedef long long LL;char s[MAX][MAX];int n,m,vis[MAX][MAX],ans;int fx[8] = {0,0,-1,1,-1,1,-1,1},fy[8] = {-1,1,0,0,-1,-1,1,1}; // 8 个方向 void dfs(int x,int y){    vis[x][y] = 1;    for(int i = 0; i < 8; i++){        int xx = x + fx[i],yy  = fy[i] + y;        if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@') // 判断是否出界, 是否已经搜索过, 是否为油田             dfs(xx,yy);    }}int main(){    while(~scanf("%d %d",&n,&m),m){        memset(vis,0,sizeof(vis));        for(int i = 0; i < n; i++)            scanf("%s",s[i]);        ans = 0;        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)                if(!vis[i][j] && s[i][j] == '@')                    ans++,dfs(i,j); // 第一次搜到 + 1         printf("%d\n",ans);    }    return 0;}



BFS:

#include<cstdio>#include<queue>#include<cstring>#include<algorithm>using namespace std;const int MAX = 1e2 + 10;typedef long long LL;char s[MAX][MAX];int n,m,vis[MAX][MAX],ans;int fx[8] = {0,0,-1,1,-1,1,-1,1},fy[8] = {-1,1,0,0,-1,-1,1,1};struct node{    int x,y;};void bfs(int x,int y){    vis[x][y] = 1;    queue <node> q;    node o;    o.x = x,o.y = y;    q.push(o);    while(!q.empty()){        o = q.front();        q.pop();        for(int i = 0; i < 8; i++){ // 8 个方向              int xx = o.x + fx[i],yy = o.y + fy[i];            if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@'){  // 判断是否出界, 是否已经搜索过, 是否为油田                 node w;                vis[xx][yy] = 1;                w.x = xx,w.y = yy;                q.push(w);            }        }    }}int main(){    while(~scanf("%d %d",&n,&m),m){        memset(vis,0,sizeof(vis));        for(int i = 0; i < n; i++)            scanf("%s",s[i]);        ans = 0;        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)                if(!vis[i][j] && s[i][j] == '@')                    ans++,bfs(i,j); // // 第一次搜到 + 1          printf("%d\n",ans);    }    return 0;}






原创粉丝点击