1. 程式人生 > >2018年藍橋杯B組c/c++ 第九題詳解

2018年藍橋杯B組c/c++ 第九題詳解

標題:全球變暖

你有一張某海域NxN畫素的照片,".“表示海洋、”#"表示陸地,如下所示:

.......
.##....
.##....
....##.
..####.
...###.
.......

其中"上下左右"四個方向上連在一起的一片陸地組成一座島嶼。例如上圖就有2座島嶼。

由於全球變暖導致了海面上升,科學家預測未來幾十年,島嶼邊緣一個畫素的範圍會被海水淹沒。具體來說如果一塊陸地畫素與海洋相鄰(上下左右四個相鄰畫素中有海洋),它就會被淹沒。

例如上圖中的海域未來會變成如下樣子:

.......
.......
.......
.......
....#..
.......
.......

請你計算:依照科學家的預測,照片中有多少島嶼會被完全淹沒。

【輸入格式】
第一行包含一個整數N。 (1 <= N <= 1000)
以下N行N列代表一張海域照片。

照片保證第1行、第1列、第N行、第N列的畫素都是海洋。

【輸出格式】
一個整數表示答案。

【輸入樣例】

7 
.......
.##....
.##....
....##.
..####.
...###.
.......  

【輸出樣例】
1

資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗 < 1000ms

請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。

注意:
main函式需要返回0;
只使用ANSI C/ANSI C++ 標準;
不要呼叫依賴於編譯環境或作業系統的特殊函式。
所有依賴的函式必須明確地在原始檔中 #include
不能通過工程設定而省略常用標頭檔案。

提交程式時,注意選擇所期望的語言型別和編譯器型別。

//深度優先搜尋找出所有的沒有淹沒之前的島嶼數量count  更新島嶼,計算出淹沒之後的島嶼數量num
//使用了標記陣列
// if(count > num) 輸出count - num
//else 輸出0
//遍歷了兩次,但是有一個bug就是如果正好有一塊島嶼被淹沒,又出現了另外一塊島嶼被分成了兩座島嶼,
//實際上應該輸出1,但是程式輸出結果為0;測試資料為第三組。

第一組測試資料
/*
7
.......
.##....
.##....
....##.
..####.
...###.
.......
*/

第二組測試資料
/*
8
.#.....#
####.###
########
###..###
###....#
.##..###
.#...#..
........
*/

第三組測試資料
/*
8
.#.....#
...#.###
########
###..###
###....#
.##..###
.#...#..
........
*/

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1000+10;

int id[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int idx[maxn][maxn];
int idx1[maxn][maxn];
char map[maxn][maxn];
int  n;
int count = 0;			//統計淹沒之前的島嶼數量
int num = 0;			//統計淹沒之後還存在的島嶼數量

bool check(int x, int y){//為統計淹沒之後的島嶼做準備
	for(int i = 0; i < 4; i++){
		int nx = x + id[i][0];
		int ny = y + id[i][1];
		if(map[nx][ny] != '#' || nx < 0 || nx >= n || ny < 0 || ny >= n){
			return false;
		}
	}
	return true;
}
void dfs(int x, int y){//統計更新之前的島嶼數量
	if(x >= 0 && x < n && y >= 0 && y < n && map[x][y] == '#' && idx[x][y] == 0){
		idx[x][y] = 1;
		if(check(x, y)) idx[x][y] = 2;
		for(int i = 0; i < 4; i++){
			int nx = x + id[i][0];
			int ny = y + id[i][1];
			dfs(nx, ny);
		}
	}else{
		return;
	}
}

void dfs1(int x, int y){//統計更新之後的島嶼數量
	if(x >= 0 && x < n && y >= 0 && y < n && idx[x][y] == 2 && idx1[x][y] == 0){
		idx1[x][y] = 1;
		for(int i = 0; i < 4; i++){
			int nx = x + id[i][0];
			int ny = y + id[i][1];
			dfs1(nx, ny);
		}
	}else{
		return;
	}
}

int main(){
	memset(idx, 0, sizeof(idx));
	memset(idx1, 0, sizeof(idx1));

	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		cin >> map[i];
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			if(map[i][j] == '#' && idx[i][j] == 0){
				count++;
				dfs(i,j);
			}
		}
	}

	for(int i = 0;i < n; i++){
		for(int j = 0; j < n; j++){
			if(idx[i][j] == 2 && idx1[i][j] == 0){
				num++;
				dfs1(i,j);
			}
		}
	}

	if(count > num) cout << count-num << endl;
	else cout << 0 << endl;
	return 0;
}