Oil Deposits
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Practice
HDU 1241
Description
GeoSurvComp地质调查公司负责探测地下石油储藏。 GeoSurvComp现在在一块矩形区域探测石油,并把这个大区域分成了很多小块。他们通过专业设备,来分析每个小块中是否蕴藏石油。如果这些蕴藏石油的小方格相邻,那么他们被认为是同一油藏的一部分。在这块矩形区域,可能有很多油藏。你的任务是确定有多少不同的油藏。
Input
输入可能有多个矩形区域(即可能有多组测试)。每个矩形区域的起始行包含m和n,表示行和列的数量,1<=n,m<=100,如果m =0表示输入的结束,接下来是n行,每行m个字符。每个字符对应一个小方格,并且要么是'*',代表没有油,要么是'@',表示有油。
Output
对于每一个矩形区域,输出油藏的数量。两个小方格是相邻的,当且仅当他们水平或者垂直或者对角线相邻(即8个方向)。
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
比较基础的DFS搜索题
方法一:
//AC...DFS堆栈写法
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
int mark[110][110];
int Move[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
char str[110][110];
int n,m;
struct data
{
int x;
int y;
};
void dfs(int x,int y)
{
stack<data> stk;
data t,tt;
t.x=x;
t.y=y;
stk.push(t);
while (!stk.empty())
{
t=stk.top();
if (mark[t.x][t.y])
stk.pop();
else
{
mark[t.x][t.y]=1;
for (int i=0;i<8;i++)
{
tt.x=Move[i][0]+t.x;
tt.y=Move[i][1]+t.y;
if (tt.x<0||tt.y<0||tt.x>=n||tt.y>=m)
continue;
if (!mark[tt.x][tt.y]&&str[tt.x][tt.y]=='@')
stk.push(tt);
}
}
}
}
int main()
{
while (scanf("%d%d",&n,&m)&&n&&m)
{
int num=0;
memset(mark,0,sizeof(mark));
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
scanf(" %c",&str[i][j]);
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (str[i][j]=='@'&&!mark[i][j])
{
++num;
dfs(i,j);
}
}
}
printf("%d\n",num);
}
return 0;
}
方法二:
//AC...DFS递归写法
#include<cstdio>
#include<cstring>
int mark[110][110];
int Move[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
char str[110][110];
int n,m;
struct data
{
int x;
int y;
};
void dfs(int x,int y)
{
int xx,yy;
if (mark[x][y])
return ;
else
{
mark[x][y]=1;
for (int i=0;i<8;i++)
{
xx=x+Move[i][0];
yy=y+Move[i][1];
if (xx<0||yy<0||xx>=n||yy>=m)
continue;
if (!mark[xx][yy]&&str[xx][yy]=='@')
dfs(xx,yy);
}
}
}
int main()
{
while (scanf("%d%d",&n,&m)&&n&&m)
{
memset(mark,0,sizeof(mark));
int num=0;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
scanf(" %c",&str[i][j]);
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (str[i][j]=='@'&&!mark[i][j])
{
num++;
dfs(i,j);
}
}
}
printf("%d\n",num);
}
return 0;
}