题目:

算法竞赛入门经典第二版 刘汝佳 P162例题6-12
例题6-12 油田 图DFS

思路:

恕臣愚钝 这题目我一开始都没看懂两个八连块怎么数出来的。。
仔细读了N遍。。原来就是数油田,相连的就属于同一块,所以这里是两坨油田。。
之前老师上课都讲过原题哎可惜我没听
八连块的八指的是以一个符号为中心,九宫格中其他的八个,也就是递归遍历的范围

看完书自己再梳理一下思路:

  1. 递归: 从第一个开始遍历符号,如果是油田 ‘ @’,则将其编号并且查询附近的8个格子,一旦查找到有油田的,编上相同的序号并以该油田为中心查找附近的8个格子。(实现了DFS)
  2. 标记和计数:用一个数组,初始化都存的0,第一次遇到油田即从1开始存储(cnt),只要是相邻的8个格子中的油田编号都相同,没有相同的就cnt加一,说明一个油田已经查找完毕,如果再发现油田就是第二个了。最后直接输出 cnt 就是有 “几坨” 油田

具体的代码实现:

  • 两个数组,一个字符型,一个 int 型用于存储编号cnt
  • 编号函数(递归函数),一旦查找到油田就将其编号,如果九宫格的其他8个格子里还有油田就递归调用继续编号。
  • 编号可以用于判断状态,如出界、不是油田、没有遍历过,idx 数组的值都会是0.如果遍历过且是油田数组存的值就是非0
  • 字符串输入,可以看到油田中没有空格输入,都是直接输入一行的字符串存储。(学到了。。因为我之前不会)
 		for(int i=0; i<m; i++)
			scanf("%s",pic[i]);//字符串输入二维数组的一行字符

代码:

#include<cstdio>
#include<cstring>

const int maxn=100+5;
char pic[maxn][maxn];
int m,n,idx[maxn][maxn];

void dfs(int r,int c,int id)//编号函数 
{
	//对相邻的格子进行判断 
	if(r>=m||r<0||c>=n||c<0)return;//出界
	if(pic[r][c]!='@'||idx[r][c]>0)return;//不是油田或者已经编号过的油田 
	 
	//编号油田并且以该油田为中心找相邻的八个格子 
	idx[r][c]=id;
	for(int dr=-1;dr<=1;dr++)
		for(int dc=-1;dc<=1;dc++)
			if(dr!=0 || dc!=0) dfs(r+dr,c+dc,id);//递归实现DFS 
}
int main()
{
	while(scanf("%d%d", &m, &n)==2 && m && n)
	{
		for(int i=0;i<m;i++)
			scanf("%s",pic[i]);//通过字符串输入 
		memset(idx, 0, sizeof(idx));//初始化 
		int cnt=0;
		for(int i=0;i<m;i++)	
			for(int j=0;j<n;j++)
				if(pic[i][j]=='@' && idx[i][j]==0) dfs(i,j,++cnt);//如果是油田且没有编号就将其编号 
		printf("%d\n",cnt); 			
	}
	return 0;
} 


运行:

例题6-12 油田 图DFS

相关文章:

  • 2021-12-04
  • 2022-01-22
  • 2022-12-23
  • 2022-12-23
  • 2021-12-26
  • 2022-12-23
  • 2021-10-05
  • 2021-10-26
猜你喜欢
  • 2021-07-05
  • 2021-11-22
  • 2022-12-23
  • 2021-05-17
  • 2022-12-23
  • 2022-12-23
  • 2021-07-17
相关资源
相似解决方案