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); 
}

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