油田(UVA572图的搜索)

题目:
某石油公司勘探地下油田资源,在一长方形区域中工作。他们的勘探方案是,首先将油田划分成许多小正方形区域,然后分别探测每一块小正方形区域是否有油。含有油就为油田。如果相邻两个(水平、垂直或对角线相邻)油田,就位相同油藏的一部分。油藏尽可能多的包含油田(油田的个数不超过100)。你的工作是确定这个长方形地域中包含多少个不同的油藏。
输入:
输入文件中包含一个或多个长方形地域。每个地域的第一行都有两个正整数m和n(1<=m,n<=100),表示地域的行数和列数。如果m=0,则表示输入结束;否则此后有m行,每行都有n个字符。每个字符都对应一个正方形区域,字符*表示没有油田,字符@表示有油。
输出:对于每个长方形区域,都单行输出油藏的个数。

输入样例:
1 1
*
3 5
@@*
@
@@*
1 8
@@***@
5 5
****@
@@@
@**@
@@@
@
@@**@
0 0

输出样例
0
1
2
2
题解:
对于这样的油田遍历,从每个“@”格子出发,寻找特它周围所有的“@”格子,同时将这些格子标记一个连通分量号,最后数连通分量数。使用图的深度优先搜索即可。
样例4,其油藏的个数就是连通分量的个数,如下图
在这里插入图片描述
八个方向的坐标变化,注意写代码是判断越界
在这里插入图片描述
代码:

#include<bits/stdc++.h>
#define REP(i,b,e) for(int i=(b);i<=(e);i++)
using namespace std;

const int maxn=100+5;
string str[maxn];//存储字符矩阵 
int m,n,setid[maxn][maxn];//行列,连通分量号 

void dfs(int x,int y,int id)//行列和连通分量号 
{
	if(x<0||x>=m||y<0||y>=n) return ;//出界
	if(setid[x][y]>0||str[x][y]!='@') return ;//已有连通分量号或不是'@' 
	setid[x][y]=id;
	REP(dx,-1,1)
		REP(dy,-1,1)
			if(dx!=0||dy!=0)
				dfs(x+dx,y+dy,id);//八个方向深搜 ,把连通的都赋值一样的数值,就是连通分量号,总之不为0
 }
 
 int main()
 {
 	while((cin>>m>>n)&&m&&n)
 	{
 		REP(i,0,m-1)
 			cin>>str[i];
 		memset(setid,0,sizeof(setid));
 		int cnt=0;
 		REP(i,0,m-1)
 			REP(j,0,n-1)
 				if(setid[i][j]==0&&str[i][j]=='@')//只要为0就表示没有搜过,或者和别的块不连通,就可以是一个新的油藏
 					dfs(i,j,++cnt);
 		cout<<cnt<<endl;
	 }
	 return 0;
  } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值