HDU - 1241 Oil Deposits (kuangbin - 简单搜索)

该博客介绍了一种使用宽度优先搜索(BFS)解决二维矩阵中 '@' 符号连通块计数的问题。题目要求找出所有相邻的 '@' 符号,并将它们视为一个连通块。在遍历矩阵时,遇到 '@' 符号就进行BFS操作,将其转换为 '*' 并递归处理同一连通块的其他 '@'。最终输出连通块的数量。代码中使用C++实现,通过读取输入矩阵,逐行处理并调用BFS函数来找出并标记连通块,最后输出连通块总数。
摘要由CSDN通过智能技术生成

题目描述(已转换成中文)

  给定一个矩形区域,询问有多少个全为‘@’的连通块。a与b属于同一连通块当且仅当至少满足下列的一个条件:
  1,a与b相邻。(当a在以b为中心的8个位置中的一个时,认为a与b相邻)
  2,a的相邻点与b或b的相邻点属于同一连通块。
  3,b的相邻点与a或a的相邻点属于同一连通块。

输入格式

  输入可能有多个矩形区域(即可能有多组测试)。每个矩形区域的起始行包含m和n,表示行和列的数量,1<=n,m<=100。当m =0时,输入结束。
  接下来是n行,每行m个字符。每个字符对应一个小方格,要么是’*’,代表禁止区域,要么是’@’。

输出格式

  对于每一个矩形区域,输出’@'的连通块数量。

输入输出样例
输入

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

输出

0
1
2
2

题目链接

分析:

  这道题是常规的bfs求连通块,bfs函数中如果遇到’@‘直接把’@‘变成’*’,因为在bfs函数中能达到的’@‘都是与bfs(x, y)同属一个连通块,接着递归调用bfs函数,直到属于同一个连通块的’@‘都被处理完为止。
  在遍历矩阵的时候记录’@‘的数量即可,因为同属于一个连通块的’@‘已经被处理成’*'了。

这道题需要注意的地方:

  在读入一个个字符的时候,我们平时用的是scanf,但回车也算是字符,所以要在每一行字符读入之后加个getchar()以消去回车,便于下一行字符的读入,但是做了这道题之后,我用cin输入一个个字符则不需要额外的getchar()消去回车。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int m, n;
char a[105][105];
int b[8][2] = {1, 0, -1, 0, 0, 1, 0, -1, 1, -1, 1, 1, -1, 1, -1, -1};
int read(){
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
	return x * f;
}
void bfs(int x, int y){
	int i, p, q;
	for(i = 0; i < 8; i++){
		p = x + b[i][0];
		q = y + b[i][1];
		if(p >= 0  && p < m && q >= 0 && q < n && a[p][q] == '@'){
			a[p][q] = '*';
			bfs(p, q);
		}
	}
}
int main(){
	int i, j, s;
	while(1){
		s = 0;
		m = read();
		if(m == 0) break;
		n = read();
		for(i = 0; i < m; i++){
			for(j = 0; j < n; j++){
				cin >> a[i][j];
			}
		}
		for(i = 0; i < m; i++){
			for(j = 0; j < n; j++){
				if(a[i][j] == '@'){
					bfs(i, j);
					s++;
				}
			}
		}
		printf("%d\n", s); 	
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值