Lake Counting(dfs 深搜/ bfs广搜)

描述

有一块N×M的土地,雨后积起了水,有水标记为‘W’,干燥为‘.’。八连通的积水被认为是连接在一起的。请求出院子里共有多少水洼?

格式

输入格式

第一行为N,M(1≤N,M≤110)。 下面为N*M的土地示意图。

输出格式

一行,共有的水洼数。

样例

输入样例

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出样例

3

限制

时间限制: 1000 ms

内存限制: 65536 KB

一开始看题目时,怎么都看不懂这题意,感觉这字里行间是不是少了点什么描述?比如说“八连通的积水被认为是连接在一起的”这一句是不是结尾处还有话没说完。于是我就搜了下该题目,没有少字,就是这样的表述。题目的意思是找极大连通图,你把题目给的样例看成一张图,图中是不是三处有积水互相不连通,而这三处积水块内是连通的,如果‘W’的上、下、左、右、左上、右上、左下、右下都是‘.’的话,该处就是一处水洼,但这三处积水是有很多‘W’组成的,每个‘W’的上、下、左、右、左上、右上、左下、右下八个位置都不全是‘.’,这怎么找水洼?我的理解是:因为这些‘W’是联通的,所以可以将它们看作一个整体,对于这个整体,如果小规模的积水‘W’是水洼,那么这个整体也可以看做一个水洼。所以进行查找时,遇到第一个‘W’时,开始对它的八个方向进行查找,遇到下一个‘W’后,标记为‘.’,然后从这个被标记的‘W’开始进行下一次查找,循环直到该积水处的最后一个‘W’的八个方向都是‘.’为止,也就找到一处水洼。当搜索完整个土地,那么会找到所有的水洼。

题目有深搜和广搜两种搜索思路,深搜是一条路直走到低然后走下一条路,广搜是用队列,可以认为是同时走多条路,不过是有先后顺序走。

题目偏向于模板型,读懂题目意思后你会发现不难名单不要犯一些小错误。。。比如当使用scanf()输入时,忘记用getchar()吸收回车符。。。用cin可以不管。

//dfs

#include<bits/stdc++.h> 
using namespace std;

char a[115][115];
char que[115];
int dx[8] = {-1,  0,  1, -1, 1, -1, 0, 1};
int dy[8] = {-1, -1, -1,  0, 0,  1, 1, 1};
int ans=0, n, m;;

void dfs(int, int);
void linkLake();

int main()
{
	scanf ("%d %d", &n, &m);
        //getchar();        “血”的教训,一定不要忘了吸回车,当只过了60%时,
                            //我查了好久才发现是这里除了问题。。。
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
                        //scanf ("%d", &a[i][j]);  如果不加上面的getchar(),那只能过60%
			cin >> a[i][j]);
		}
                //getchar();       
	}
	linkLake();
	printf ("%d\n", ans);
	return 0;
} 

void linkLake() {
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
			if (a[i][j] == 'W') {
				dfs(i, j);
				ans++;
			}
		}
	}
}

void dfs(int x, int y) {
	for (int i=0; i<8; i++) {
		int tmpx = x + dx[i];
		int tmpy = y + dy[i];
		if (tmpx < n && tmpx >= 0 && tmpy < m && tmpy >=0 && a[tmpx][tmpy] == 'W') {
			a[tmpx][tmpy] = '.';
			dfs(tmpx, tmpy);
		}
	}
}

 bfs广搜,因为我看很多解法是用stl的queue来做的,所以我想用用数组充当队列试试,如果用stl的queue,则一般的写法是命名结构体,queue的数据类型是该结构体。

//bfs
#include<bits/stdc++.h> 
using namespace std;

char a[115][115];
int que[10005][3];
int dx[8] = {-1,  0,  1, -1, 1, -1, 0, 1};
int dy[8] = {-1, -1, -1,  0, 0,  1, 1, 1};
int ans=0, n, m;;

void bfs(int, int);

int main()
{
	scanf ("%d %d", &n, &m);
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
			cin >> a[i][j];
		}
	}
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
			if (a[i][j] == 'W') {
				ans++;
				bfs(i, j);
			}
		}
	}
	printf ("%d\n", ans);
	return 0;
} 

void bfs(int x, int y) {
	que[1][1] = x;
	que[1][2] = y;
	int head = 1, tail = 1;
	while (head <= tail) {
		for (int i=0; i<8; i++) {
			int tmpx = que[head][1] + dx[i];
			int tmpy = que[head][2] + dy[i];
			if (tmpx < n && tmpx >= 0 && tmpy < m && tmpy >=0 && a[tmpx][tmpy] == 'W') {
				a[tmpx][tmpy] = '.';
				tail++;
				que[tail][1] = tmpx;
				que[tail][2] = tmpy;
				
			}
		}
		head++;
	}
	
}
发布了89 篇原创文章 · 获赞 77 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/wodemaoheise/article/details/105119076