2019_GDUT_新生专题I选集DFS/BFS解连通块问题

跟風遠走 提交于 2020-01-13 17:06:32

2019_GDUT_新生专题I选集DFS/BFS解连通块问题


题目链接:http://poj.org/problem?id=2386
题意:由于最近的降雨,在农夫约翰田地的不同地方积聚了水,用N x M(1 <= N <= 100; 1 <= M <= 100)正方形的矩形表示。 每个方格包含水(‘W’)或旱地(’。’)。 农夫约翰想弄清楚他的田地里形成了多少个池塘。 池塘是一组相连的正方形,里面有水,其中一个正方形被认为与八个池塘相邻。给定农夫约翰的田野图,确定他有多少个池塘。

搜索里面经典的连通块问题,思路是比较简单的,在找到某个地方有积水后,从这一格开始往八个不同的方向找有没有积水。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int map[1005][1005];
int ax[8]={-1,0,1,-1,1,-1,0,1};
int ay[8]={-1,-1,-1,0,0,1,1,1};
void dfs(int x,int y){
	if (!map[x][y]) return;
	map[x][y]=0;
	for (int i=0;i<8;i++)
		dfs(x+ax[i],y+ay[i]);//遍历积水附近的八个格子
	return;
}
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	char c;
	getchar();
	for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)
			{
				c=getchar();
				if (c=='W') map[i][j]=1;
				else map[i][j]=0;
			}
			getchar();
		}
	int ans=0;//ans记录找到的池塘数
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			if (map[i][j]) 
			{
				ans++;
				dfs(i,j);
			}
	printf("%d\n",ans);
	return 0;
}

题目链接:http://poj.org/problem?id=1979

题意:有一个长方形的房间,覆盖着正方形的瓷砖。 每个图块都用红色或黑色着色。 一个人站在黑色的瓷砖上。 他可以从一个图块移动到四个相邻图块之一。 但是他不能在红色瓷砖上移动,只能在黑色瓷砖上移动。

编写一个程序,通过重复上述动作来计算他可以到达的黑色瓷砖的数量。

与前面那题类似,只是联通的规则由八向变成四向,而且只需要求特定的联通块的大小,那么只需要在读入的时候记录起点然后dfs就可。

另外是多组数据输入,记得每次初始化好就行。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int map[1005][1005],ans=0;
int ax[4]={-1,0,1,0};
int ay[4]={0,-1,0,1};
void dfs(int x,int y){
	if (!map[x][y]) return;
	map[x][y]=0;
	ans++;
	for (int i=0;i<=3;i++)
		dfs(x+ax[i],y+ay[i]);
	return;
}
int main(){
	int n,m,x,y;
	scanf("%d %d",&n,&m);
	while (n||m){
	char c;
	getchar();
	for (int i=1;i<=m;i++)
		{
			for (int j=1;j<=n;j++)
			{
				c=getchar();
				if (c=='#') map[i][j]=0;
				else map[i][j]=1;
				if (c=='@')
				{
					x=i;
					y=j;
				}//记录起点位置
			}
			getchar();//清楚缓冲区的换行符
		}
	ans=0;//ans用于记录目标连通块大小
	for (int i=1;i<=m;i++) map[i][n+1]=0;
	for (int i=1;i<=n;i++) map[m+1][i]=0;//设置边界
	dfs(x,y);
	printf("%d\n",ans);
	scanf("%d %d",&n,&m);
	}
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!