油田问题(Oil Deposits)(DFS 处理连通块)

传送门:Oil Deposits - UVA 572 - Virtual Judge

题目详情:

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.

翻译 :
某公司负责探测地下油层,每次处理一个大的矩形区域。先创建一个网格,将土地划分为许多方形块,然后用传感设备分别探测每个地块,以确定该地块是否含有石油。一块含有石油的土地叫做pocket。如果两个pocket边相邻或对角相邻,则它们属于同一油层的一部分。你的工作是确定在一个网格有多少不同的油层。

输入:

输入包含多组数据。每组数据都以包含m和n的一行开始,m和n是网格中行和列的数量(1 <= m <= 100,1 <= n <= 100),由一个空格分隔。如果m = 0,则表示输入结束。下面是m行,每行有n个字符(不包括行尾字符)。每个字符对应一块土地,要么是“*”,代表没有油,要么是“@”,代表一个pocket。

输出:

输出网格有多少不同的油层。

Sample Input

1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0

Sample Output

0
1
2
2

代码实现

#include<stdio.h> 
#include<string.h>
int vis[110][110], m, n, cnt;
char mp[110][110];
int next[8][2] = {-1,0, -1,1, 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1};
void dfs(int x, int y) {
//	vis[x][y] = 1;
	int tx, ty;
	for (int k = 0; k < 8; k++) {// 利用循环朝八个方向遍历 
		//更新变量 
		tx = x + next[k][0];
		ty = y + next[k][1];
		
		//判断边界 
		if (tx < 1 || tx > m || ty < 0 || ty >= n) continue;
		
//		if (mp[x][y] == '*' || vis[x][y] != 0) continue;
		
		// 这个点必须,没走过 ,并且是油田 ‘@ ’ 
		if (!vis[tx][ty] && mp[tx][ty] == '@') {
			vis[tx][ty] = 1;// 标记已经走过了
			//向下一个点深搜 
			dfs(tx, ty);
		}
	}
	return ;
	
}

int main() {
	while (scanf("%d%d", &m, &n) && m && n) {
//		getchar();
		for(int i = 1; i <= m; i++) {
			scanf("%s", mp[i]);// 说明后面要从 第 0 列开始遍历 
		}
		//初始化记号数组 vis 
		memset(vis, 0, sizeof(vis));
		cnt = 0;
		
		for (int i = 1; i <= m; i++) {
			for (int j = 0; j < n; j++) {//错误原因: 1,j应该从零开始,因为输入时一次输入一行 默认从第 0  列开始 
				if (!vis[i][j] && mp[i][j] == '@') {
//					vis[i][j] = 1;
					dfs(i, j);
					cnt++;
				}
			}
		}
		printf("%d\n", cnt);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值