给你一张某一海域卫星照片,你需要统计:
照片中海岛的数目
照片中面积不同的海岛数目
照片中形状不同的海岛数目
其中海域的照片如下,”.”表示海洋,”#”表示陆地。在”上下左右”四个方向上连在一起的一片陆地组成一座岛屿。
.####..
.....#.
####.#.
.....#.
..##.#.
上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是”####”,所以形状不同的岛屿数目为3。
输入
第一行包含两个整数:N 和 M,(1 ≤ N, M ≤ 50),表示照片的行数和列数。
以下一个 N * M 的矩阵,表示表示海域的照片。
输出
输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。
样例输入
5 7
.####..
.....#.
####.#.
.....#.
..##.#.
样例输出
4 2 3
思路很简单,直接dfs即可,不过,需要在搜索的过程中,记录#的数量,来表示面积,记录遍历路径,使用相对位置表示形状。
参考代码(很长,很乱,仅供参考,不建议复制粘贴):
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
struct point {//用一个结构体的表示路径中的点,方便记录岛屿的形状
int x;
int y;
point(int m, int n) {
x = m;
y = n;
}
};
struct mycomp//形状set kind的自动以排序函数
{
bool operator () (const std::vector<point>& a, const std::vector<point>& b) const
{
if (a.size() == b.size()) {
for (int i = 0; i < a.size(); i++) {
if (a[i].x == b[i].x) {
if (a[i].y == b[i].y) {
continue;
}
return a[i].y > b[i].y;
}
return a[i].x > b[i].x;
}
return false;
}
return a.size() > b.size();
}
};
void dfs(int i, int j, std::vector<std::vector<bool> > &visited, std::vector<std::vector<char> > &grid, int &area, std::vector<point> &points) {//dfs主要实现函数
int n = grid.size();
int m = grid[0].size();
if (i < 0 || i >= n)
return;
if (j < 0 || j >= m)
return;
if (visited[i][j] || grid[i][j] == '.')
return;
visited[i][j] = true;
point p(i, j);
points.push_back(p);
area++;
dfs(i - 1, j, visited, grid, area, points);
dfs(i + 1, j, visited, grid, area, points);
dfs(i, j - 1, visited, grid, area, points);
dfs(i, j + 1, visited, grid, area, points);
}
int main() {
using namespace std;
int n, m;
while (cin >> n >> m) {
vector<vector<char> > grid(n, vector<char>(m));
vector<vector<bool> > visited(n, vector<bool>(m, false));
int islandNums = 0;
set<int> areas;//面积集合,表示不同面积的岛屿个数
set<vector<point>, mycomp > kinds;//形状集合,表示不同形状的岛屿个数
int area = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '#' && !visited[i][j]) {
vector<point> points;
dfs(i, j, visited, grid, area, points);
islandNums++;
areas.insert(area);
area = 0;
for (int k = points.size() - 1; k >= 0; k--) {
points[k].x -= points[0].x;
points[k].y -= points[0].y;
}
kinds.insert(points);
}
}
}
cout << islandNums << " " << areas.size() << " " << kinds.size() << endl;
}
return 0;
}