#1310 : 岛屿

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给你一张某一海域卫星照片,你需要统计:

1. 照片中海岛的数目

2. 照片中面积不同的海岛数目

3. 照片中形状不同的海盗数目

其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。

  1. .####..
  2. .....#.
  3. ####.#.
  4. .....#.
  5. ..##.#.

上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。

输入

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

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

输出

输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。

样例输入
  1. 5 7
  2. . # # # # . .
  3. . . . . . # .
  4. # # # # . # .
  5. . . . . . # .
  6. . . # # . # .
样例输出
  1. 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个坐标与其第一个坐标的坐标差,如果有一个不相等,则形状不同)。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <set>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7.  
  8. int N, M;//N为行数,M为列数
  9. char map[][];//存储字符矩阵
  10. bool visit[][];//作为标记的数组
  11.  
  12. int dx[] = {-, , , };//方向数组,为了优化dfs代码
  13. int dy[] = {, , , -};
  14. int area = ;
  15.  
  16. int NumOfIslands = , NODAI = , NODCI;//最终NumOfIslands表示岛屿数,NODAI表示不同面积的岛屿数,
  17. //计算过程中NumOfIslands也作为某个岛屿的编号,岛屿编号从0开始
  18.  
  19. struct position {
  20. int x;
  21. int y;
  22. };
  23.  
  24. int num[];//num[i]存储了编号i岛屿的面积大小
  25.  
  26. struct position a[][];//表示最多有300个岛屿,每个岛屿最大面积为300即对应300个坐标
  27.  
  28. bool flag[];
  29.  
  30. bool cmp(struct position a, struct position b){
  31. if(a.x != b.x)
  32. return a.x < b.x;
  33. else
  34. return a.y < b.y;
  35. }
  36.  
  37. int isSame(struct position *c, struct position *d, int x, int y){//判断两个岛屿形状是否相同
  38. int flag = ;
  39. if(num[x] != num[y])
  40. return ;
  41. for(int i = ; i < num[x]; i++){
  42. if(((c[i].x - c[].x) == (d[i].x - d[].x))&& ((c[i].y - c[].y)== (d[i].y - d[].y)))
  43. continue;
  44. else {
  45. flag = ;
  46. break;
  47. }
  48. }
  49. return flag;
  50. }
  51.  
  52. void dfs(int x, int y){
  53. a[NumOfIslands][area].x = x;//保存第NumOfIslands个岛屿第area个坐标x的值
  54. a[NumOfIslands][area].y = y;
  55. area++;//面积数加1
  56. visit[x][y] = ;//标记坐标(x,y)为已访问
  57. for(int i = ; i < ; i++){
  58. int nx = x + dx[i];
  59. int ny = y + dy[i];
  60. if(nx >= && nx < N && ny >= && ny < M && map[nx][ny] == '#' && visit[nx][ny] == )
  61. dfs(nx, ny);
  62. }
  63. }
  64.  
  65. int main(){
  66.  
  67. set<int> v;
  68. int i, j;
  69.  
  70. cin >> N >> M;
  71. //输入字符矩阵
  72. for(i = ; i < N; i++)
  73. cin >> map[i];
  74.  
  75. for(i = ; i < N; i++) {
  76. for(j = ; j < M; j++){
  77. if(map[i][j] == '#' && visit[i][j] == ){
  78. area = ;//初始化某个岛屿的面积数为0
  79. dfs(i, j);
  80. num[NumOfIslands] = area;
  81. v.insert(area);
  82. NumOfIslands++;
  83. }
  84. }
  85. }
  86.  
  87. NODAI = v.size();//面积不同的岛屿数
  88.  
  89. NODCI = NumOfIslands;
  90.  
  91. //对每个岛屿的坐标进行排序,方便比较两个岛屿形状是否相同
  92. for(i = ; i < NumOfIslands; i++){
  93. sort(a[i], a[i] + num[i], cmp);
  94. }
  95.  
  96. //计算形状不同的岛屿数
  97. for(i = ; i < NumOfIslands - ; i++){
  98. if(flag[i] == ){
  99. continue;
  100. }
  101. else {
  102. for(j = i+; j < NumOfIslands; j++) {
  103. if((flag[j] == ) && (isSame(a[i], a[j], i, j))){
  104. flag[j] = ;
  105. NODCI--;
  106. }
  107. }
  108. }
  109.  
  110. }
  111.  
  112. cout << NumOfIslands << " " << NODAI << " " << NODCI << endl;
  113. //system("pause");
  114. return ;
  115. }
 

hihocoder 1310 岛屿的更多相关文章

  1. hiho #1310 : 岛屿 (dfs,hash)

    题目2 : 岛屿 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给你一张某一海域卫星照片,你需要统计: 1. 照片中海岛的数目 2. 照片中面积不同的海岛数目 3. 照 ...

  2. hihocoder offer收割编程练习赛11 C 岛屿3

    思路: 并查集的应用. 实现: #include <iostream> #include <cstdio> using namespace std; ][]; int n, x ...

  3. hihocoder 1176

    hihocoder 1176 题意:N,M.分别表示岛屿数量和木桥数量,一笔画 分析:欧拉路问题(给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路) 欧拉路的条件 一个无向 ...

  4. 【HIHOCODER 1176】 欧拉路·一

    描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的角色来到了一个很大的湖边.湖上有N个小岛(编号1..N),以及连接小岛的 ...

  5. 【[Offer收割]编程练习赛11 C】岛屿3

    [题目链接]:http://hihocoder.com/problemset/problem/1487 [题意] 中文题 [题解] 岛屿的数目对应了这个图中联通块的数目; 面积则对应有多少个方块; 周 ...

  6. [LeetCode] Island Perimeter 岛屿周长

    You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represen ...

  7. [LeetCode] Number of Islands II 岛屿的数量之二

    A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...

  8. [LeetCode] Number of Islands 岛屿的数量

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  9. hihocoder -1121-二分图的判定

    hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...

随机推荐

  1. HDU 5531 Rebuild (2015长春现场赛,计算几何+三分法)

    Rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  2. Jvm基础(1)-Java运行时数据区

    最近在看<深入理解Java虚拟机>,里面讲到了Java运行时数据区,这是Jvm基本知识,把读书笔记记录在此.这些知识属于常识,都能查到的,如果我有理解不对的地方,还请指出. 首先把图贴上来 ...

  3. 删除MySQL重复数据

    删除MySQL重复数据 项目背景 在最近做的一个linux性能采集项目中,发现线程的程序入库很慢,再仔细定位,发现数据库里面很多冗余数据.因为在采集中,对于同一台设备,同一个时间点应该只有一个数据,然 ...

  4. PAC(Proxy Auto Config)代理自动配置文件的编写

    Proxy Auto Config文件格式说明 PAC文件实际上是一个Script, 通过PAC我们可以让系统根据情况判断使用哪一个Proxy来访问目标网址, 这样做的好处: 分散Proxy的流量,避 ...

  5. ID生成器的一种可扩展实现方案

    ID生成器主要为了解决业务程序生成记录ID的场景,而一个好的ID生成器肯定要满足扩展性好.并发性好的特点,本文下面介绍一种满足上述特点的实现方案. 此方案的核心思想是:每次需要扩容机器时,将每个节点维 ...

  6. union all 简单用法

    select Y.ID,sum(cast(Y.m as int)) as hefrom(select top 10 a.ID,a.AlarmSource as m from dbo.AlarmInfo ...

  7. PostgreSQL的 initdb 源代码分析之四

    继续分析: if (pwprompt && pwfilename) { fprintf(stderr, _("%s: password prompt and password ...

  8. Codeforces Round #327 (Div. 2) D. Chip 'n Dale Rescue Rangers 二分 物理

    D. Chip 'n Dale Rescue Rangers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/co ...

  9. Codeforces 278C Learning Languages(并查集)

    题意抽象出来就是求联通块的个数吧,然后添加最少边使图联通. 注意所有人都不会任何语言的时候,答案是n而不是n-1. #include<algorithm> #include<iost ...

  10. iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)

    Stroke-描边 影响描边的因素 线的宽度-CGContextSetLineWidth 交叉线的处理方式-CGContextSetLineJoin 线顶端的处理方式-CGContextSetLine ...