buaacoding ?.海洋与陆地

本来一个很简单的题因为一个极其愚蠢的错误卡了非常久……

题目描述

输入: 输入n+1行,第一行为正整数n,表示地图的大小,n<=100
之后n行每行输入n个字符,由*和#组成,其中*表示海洋,#表示陆地
两块陆地在上下左右四个方向上有间接接壤视为同属于一个大陆
例如

*#
#*

视为拥有两块大陆
输出: 有多少块大陆
输入样例

5
*###*
**##*
#****
#*#**
***##

输出样例

4

思路

每碰到一块大陆,就计数,然后把这一整块大陆变成海洋,使其不对后续的计数产生干扰。
由于某一块大陆可能有非常多的土地接壤,考虑用递归来实现所有陆地的反转。
符号并不重要,将地图二值化,*->0->海洋,#->1->陆地

采用加边法来规避数组越界的问题,将实际操作的范围规定为[1,n]*[1,n]而非从0开始计数,虽然浪费了空间,但是使得i-1和j-1的访问在物理上不会越界,不会导致程序卡死的问题,同时也简化了程序设计的逻辑。

尬点

读入时需要注意n后的回车要吃掉,每行字符串后面的回车也要吃掉,否则会导致读入的数组不正常。
之前卡了很长一段时间,是因为我在定义了一个全局变量n之后,写主函数时又手贱定义了一个n。
根据语法,这没有任何错误,在局部变量与全局变量重名时,函数内使用局部变量,这是语言的特性,也不止C有。
可是这就导致读入的n并没有保存到全局的n中,子函数中访问到的n都是0,于是全部都工作不正常,都没输出……
我还纳闷咋没输出……还以为是递归的问题,调了半天,后来尝试想把打印数组的过程写成子函数的时候发现了错误。实属hape。

参考

和过去的两个题有点像,特别是前者。
计算机导论模拟测试练习(2018年秋)I. 灯矩阵
第四次机考(2019)D. 卫星照片二

#include <stdio.h>
#define MAX 100
int n;
int map[MAX+2][MAX+2]={0};
void reverse(int i,int j);

int main(int argc, char const *argv[])
{
	int i,j,cnt=0;
	char ch;
	scanf("%d",&n);getchar();
	for(i=1;i<=n;++i)
		for(j=1;j<=n;++j)
		{
			ch=getchar();
			if(j==n) getchar();
			map[i][j]=(ch=='*')?0:1;
		}
	for(i=1;i<=n;++i)
		for(j=1;j<=n;++j)
			if(map[i][j])
			{
				++cnt;
				reverse(i,j);
			}
	printf("%d\n",cnt );
	return 0;
}

void reverse(int i,int j)
{	
	if(i<1||j<1||i>n||j>n) return ;
	map[i][j]=0;
	if(map[i-1][j]) reverse(i-1,j);
	if(map[i+1][j]) reverse(i+1,j);
	if(map[i][j-1]) reverse(i,j-1);
	if(map[i][j+1]) reverse(i,j+1); 
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章