岛屿
本题来自hihocoder #1310
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给你一张某一海域卫星照片,你需要统计:
1. 照片中海岛的数目
2. 照片中面积不同的海岛数目
3. 照片中形状不同的海岛数目
其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。
.####.. .....#. ####.#. .....#. ..##.#.
上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。
输入
第一行包含两个整数:N 和 M,(1 ≤ N, M ≤ 50),表示照片的行数和列数。
以下一个 N * M 的矩阵,表示表示海域的照片。
输出
输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。
样例输入
5 7 .####.. .....#. ####.#. .....#. ..##.#.
样例输出
4 2 3
分析
对于这道题,首先我们需要求出有多少个岛屿,这可以很容易地用dfs的方法求得,进行dfs的同时,我们顺便计算每个岛屿的面积以及dfs过程中经过的点的序列。这样,为了比较两个岛屿是否有相同的形状,只需要查看二者的dfs序列是否只差一个平移操作。这道题的代码如下:
#include<iostream> #include<vector> #include<deque> #include<stack> #include<string> #include<algorithm> #include<string.h> #include<sstream> #include<set> using namespace std; char photo[50][50]; bool is_visited[50][50]; int N, M; const int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 }, }; struct island { int S; vector<int> pos_y; vector<int> pos_x; }; void my_dfs(int i, int j, island& isl){ if (i < 0 || i >= N || j < 0 || j >= M || photo[i][j] == '.' || is_visited[i][j]) return; is_visited[i][j] = true; ++isl.S; isl.pos_y.push_back(i); isl.pos_x.push_back(j); for (int d = 0; d < 4; ++d){ int i1 = i + dir[d][0]; int j1 = j + dir[d][1]; if (i1 >= 0 && i1 <= N && j1 >= 0 && j1 <= M) my_dfs(i1, j1,isl); } return; } void get_info(vector<island>& islands){ for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) { if (photo[i][j] == '#' && !is_visited[i][j]) { island tmp; tmp.S = 0; my_dfs(i, j, tmp); islands.push_back(tmp); } } } int dif_num_of_areas(vector<island>& islands){ set<int> areas; for (int i = 0; i < islands.size(); ++i) { if (areas.find(islands[i].S) == areas.end()) areas.insert(islands[i].S); } return areas.size(); } bool shape_equal(island a, island b) { if (a.S != b.S) return false; int dif_y = a.pos_y[0] - b.pos_y[0]; int dif_x = a.pos_x[0] - b.pos_x[0]; for (int i = 0; i < a.pos_x.size(); ++i) { if (a.pos_y[i] - b.pos_y[i] != dif_y || a.pos_x[i] - b.pos_x[i] != dif_x) return false; } return true; } int dif_shapes(vector<island>& islands){ vector<int> shapes; for (int i = 0; i < islands.size(); ++i){ bool is_existed = false; for (int j = 0; j < shapes.size(); ++j){ if (shape_equal(islands[i], islands[shapes[j]])){ is_existed = true; } } if (is_existed) continue; shapes.push_back(i); } return shapes.size(); } int main() { cin >> N >> M; for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) { cin >> photo[i][j]; } vector<island> islands; //vector<int> num_of_areas; //vector<int> shapes; get_info(islands); cout << islands.size() << ' ' << dif_num_of_areas(islands) << ' ' << dif_shapes(islands) << endl; //system("pause"); return 0; }