hihocoder 1310 岛屿
2016-08-06 09:04
225 查看
#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
思路:(1)求岛屿数目很简单,初始化岛屿数目NumOfIslands为0,遍历所有的点,如果这个点未访问并且为‘#’,则NumOfIslands++,进行DFS搜索,将和这个点属于同一个岛屿的所有为'#'的点标记为已访问。
(2)求解一个岛屿时,计算它的面积,将所有的面积保存下来,去掉重复元素,剩下元素个数即为面积不同的岛屿数。
(3)DFS搜索出所有岛屿,同时把每个岛屿包含的像素坐标也保存起来并按照坐标排序(先根据x从小到大排序,如果x坐标相同,再根据y从小到大排序)。 形状相同的岛屿数目我们可以通过逐一比较岛屿的每一个像素得到。当我们比较岛屿x和岛屿y时,如果每对像素的坐标差都相同,那么x和y的形状就是相同的。(首先如果两个岛屿的面积数不同,形状肯定不同,再根据岛屿x的第i(1 <= i <= 面积-1)个坐标与其第一个坐标的坐标差 ?= 岛屿y的第i个坐标与其第一个坐标的坐标差,如果有一个不相等,则形状不同)。
#include <iostream> #include <cstdio> #include <set> #include <vector> #include <algorithm> using namespace std; int N, M;//N为行数,M为列数 char map[55][55];//存储字符矩阵 bool visit[55][55];//作为标记的数组 int dx[4] = {-1, 0, 1, 0};//方向数组,为了优化dfs代码 int dy[4] = {0, 1, 0, -1}; int area = 0; int NumOfIslands = 0, NODAI = 0, NODCI;//最终NumOfIslands表示岛屿数,NODAI表示不同面积的岛屿数, //计算过程中NumOfIslands也作为某个岛屿的编号,岛屿编号从0开始 struct position { int x; int y; }; int num[300];//num[i]存储了编号i岛屿的面积大小 struct position a[300][300];//表示最多有300个岛屿,每个岛屿最大面积为300即对应300个坐标 bool flag[300]; bool cmp(struct position a, struct position b){ if(a.x != b.x) return a.x < b.x; else return a.y < b.y; } int isSame(struct position *c, struct position *d, int x, int y){//判断两个岛屿形状是否相同 int flag = 1; if(num[x] != num[y]) return 0; for(int i = 1; i < num[x]; i++){ if(((c[i].x - c[0].x) == (d[i].x - d[0].x))&& ((c[i].y - c[0].y)== (d[i].y - d[0].y))) continue; else { flag = 0; break; } } return flag; } void dfs(int x, int y){ a[NumOfIslands][area].x = x;//保存第NumOfIslands个岛屿第area个坐标x的值 a[NumOfIslands][area].y = y; area++;//面积数加1 visit[x][y] = 1;//标记坐标(x,y)为已访问 for(int i = 0; i < 4; i++){ int nx = x + dx[i]; int ny = y + dy[i]; if(nx >= 0 && nx < N && ny >= 0 && ny < M && map[nx][ny] == '#' && visit[nx][ny] == 0) dfs(nx, ny); } } int main(){ set<int> v; int i, j; cin >> N >> M; //输入字符矩阵 for(i = 0; i < N; i++) cin >> map[i]; for(i = 0; i < N; i++) { for(j = 0; j < M; j++){ if(map[i][j] == '#' && visit[i][j] == 0){ area = 0;//初始化某个岛屿的面积数为0 dfs(i, j); num[NumOfIslands] = area; v.insert(area); NumOfIslands++; } } } NODAI = v.size();//面积不同的岛屿数 NODCI = NumOfIslands; //对每个岛屿的坐标进行排序,方便比较两个岛屿形状是否相同 for(i = 0; i < NumOfIslands; i++){ sort(a[i], a[i] + num[i], cmp); } //计算形状不同的岛屿数 for(i = 0; i < NumOfIslands - 1; i++){ if(flag[i] == 1){ continue; } else { for(j = i+1; j < NumOfIslands; j++) { if((flag[j] == 0) && (isSame(a[i], a[j], i, j))){ flag[j] = 1; NODCI--; } } } } cout << NumOfIslands << " " << NODAI << " " << NODCI << endl; //system("pause"); return 0; }
相关文章推荐
- hihoCoder1310 岛屿 (dfs)
- hihoCoder1319 岛屿周长 (bfs)
- [hihoCoder] 岛屿 解题报告
- Vostro 1310 的触摸板问题解决方法
- 项目源码--Android迷幻岛屿综合游戏
- [难]hihocoder 线段树 毁灭者问题
- hihocoder:01背包
- hihoCoder 最长回文子串(manacher算法:马拉车)
- hihocoder题目 trie树 编程总结
- hihoCoder挑战赛4 光棍节
- hihocoder第二十四周(floyd)
- hihocoder:最短路径
- hihocoder:#1105 : 题外话·堆
- hihoCoder - 1039 - 字符消除 (模拟题~)
- hihocoder1038 01背包
- hihocoder-1032
- hihocoder: 二分·二分查找之k小数
- hihoCoder 1095 HIHO Drinking Game 微软苏州校招笔试 12月27日
- 【hihocoder】01背包
- hihoCoder_推箱子