[hihoCoder太閣最新面經算法競賽2] 島嶼 (DFS,Hash Function)

描述

給你一張某一海域衛星照片,你需要統計:

1. 照片中海島的數目

2. 照片中面積不同的海島數目

3. 照片中形狀不同的海盜數目

其中海域的照片如下,"."表示海洋,"#"表示陸地。在"上下左右"四個方向上連在一起的一片陸地組成一座島嶼。

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

上圖所示的照片中一共有4座島嶼;其中3座面積爲4,一座面積爲2,所以不同面積的島嶼數目是2;有兩座形狀都是"####",所以形狀不同的島嶼數目爲3。

輸入

第一行包含兩個人整數:N 和 M,(1 ≤ NM ≤ 50),表示照片的行數和列數。

以下一個 N * M 的矩陣,表示表示海域的照片。

輸出

輸出3個整數,依次是照片中海島的數目、面積不同的海島數目和形狀不同的海島數目。

樣例輸入
5 7
.####..  
.....#.  
####.#.  
.....#.  
..##.#.  
樣例輸出
4 2 3

題解:海島數目,面積不同的海島數目都比較容易求解,該題關鍵是形狀不同的海島數目求解。有多種hash方法,這裏使用了遍歷序列字符串表示形狀。0,1,2,4分表代表4個方向。'02..'代表了島嶼是怎麼遍歷完成的,也是怎麼畫出的。

#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
#include<cstdio>
#include<unordered_map>
#include<unordered_set>
#include<cmath>
#include<climits>
#include<stack>
#include<queue>
using namespace std;
int n,m;
char grid[51][51];
bool vis[51][51];
int dir[][2]={0,1,1,0,-1,0,0,-1};
int sum,area_sum,shape_sum;
unordered_map<int,set<string>> Map;
void dfs(int x,int y,int& dep,string& op) {
    for(int i=0;i<4;i++) {
        int nex=x+dir[i][0];
        int ney=y+dir[i][1];
        if(nex<0||nex>=n||ney<0||ney>=m||!vis[nex][ney]||grid[nex][ney]=='.') continue;
        op+=(char)(i+'0');
        vis[nex][ney]=false;
        dfs(nex,ney,++dep,op);
        op+=(char)(4-i+'0');
    }
}
int main() {
	cin>>n>>m;
	for(int i=0;i<n;i++) {
        getchar();
        for(int j=0;j<m;j++) {
            scanf("%c",&grid[i][j]);
        }
	}
	memset(vis,true,sizeof(vis));
	Map.clear();
	sum=area_sum=shape_sum=0;

	for(int i=0;i<n;i++) {
        for(int j=0;j<m;j++) {
            if(vis[i][j]&&grid[i][j]=='#') {
                vis[i][j]=false;
                int dep=1;
                string op="0";
                dfs(i,j,dep,op);
                if(Map.find(dep)==Map.end()) {
                    area_sum++;
                    shape_sum++;
                    Map[dep].insert(op);
                }
                else {
                    if(Map[dep].find(op)==Map[dep].end()) {
                        shape_sum++;
                        Map[dep].insert(op);
                    }
                }
                sum++;
            }
        }
	}
	cout<<sum<<" "<<area_sum<<" "<<shape_sum<<endl;
	return 0;
}


發佈了81 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章