hihocoder 1310 岛屿
#1310 : 岛屿
描述
给你一张某一海域卫星照片,你需要统计:
1. 照片中海岛的数目
2. 照片中面积不同的海岛数目
3. 照片中形状不同的海盗数目
其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。
- .####..
- .....#.
- ####.#.
- .....#.
- ..##.#.
上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。
输入
第一行包含两个人整数:N 和 M,(1 ≤ N, M ≤ 50),表示照片的行数和列数。
以下一个 N * M 的矩阵,表示表示海域的照片。
输出
输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。
- 样例输入
-
- 5 7
- . # # # # . .
- . . . . . # .
- # # # # . # .
- . . . . . # .
- . . # # . # .
- 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[][];//存储字符矩阵
- bool visit[][];//作为标记的数组
- int dx[] = {-, , , };//方向数组,为了优化dfs代码
- int dy[] = {, , , -};
- int area = ;
- int NumOfIslands = , NODAI = , NODCI;//最终NumOfIslands表示岛屿数,NODAI表示不同面积的岛屿数,
- //计算过程中NumOfIslands也作为某个岛屿的编号,岛屿编号从0开始
- struct position {
- int x;
- int y;
- };
- int num[];//num[i]存储了编号i岛屿的面积大小
- struct position a[][];//表示最多有300个岛屿,每个岛屿最大面积为300即对应300个坐标
- bool flag[];
- 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 = ;
- if(num[x] != num[y])
- return ;
- for(int i = ; i < num[x]; i++){
- if(((c[i].x - c[].x) == (d[i].x - d[].x))&& ((c[i].y - c[].y)== (d[i].y - d[].y)))
- continue;
- else {
- flag = ;
- 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] = ;//标记坐标(x,y)为已访问
- for(int i = ; i < ; i++){
- int nx = x + dx[i];
- int ny = y + dy[i];
- if(nx >= && nx < N && ny >= && ny < M && map[nx][ny] == '#' && visit[nx][ny] == )
- dfs(nx, ny);
- }
- }
- int main(){
- set<int> v;
- int i, j;
- cin >> N >> M;
- //输入字符矩阵
- for(i = ; i < N; i++)
- cin >> map[i];
- for(i = ; i < N; i++) {
- for(j = ; j < M; j++){
- if(map[i][j] == '#' && visit[i][j] == ){
- area = ;//初始化某个岛屿的面积数为0
- dfs(i, j);
- num[NumOfIslands] = area;
- v.insert(area);
- NumOfIslands++;
- }
- }
- }
- NODAI = v.size();//面积不同的岛屿数
- NODCI = NumOfIslands;
- //对每个岛屿的坐标进行排序,方便比较两个岛屿形状是否相同
- for(i = ; i < NumOfIslands; i++){
- sort(a[i], a[i] + num[i], cmp);
- }
- //计算形状不同的岛屿数
- for(i = ; i < NumOfIslands - ; i++){
- if(flag[i] == ){
- continue;
- }
- else {
- for(j = i+; j < NumOfIslands; j++) {
- if((flag[j] == ) && (isSame(a[i], a[j], i, j))){
- flag[j] = ;
- NODCI--;
- }
- }
- }
- }
- cout << NumOfIslands << " " << NODAI << " " << NODCI << endl;
- //system("pause");
- return ;
- }
hihocoder 1310 岛屿的更多相关文章
- hiho #1310 : 岛屿 (dfs,hash)
题目2 : 岛屿 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给你一张某一海域卫星照片,你需要统计: 1. 照片中海岛的数目 2. 照片中面积不同的海岛数目 3. 照 ...
- hihocoder offer收割编程练习赛11 C 岛屿3
思路: 并查集的应用. 实现: #include <iostream> #include <cstdio> using namespace std; ][]; int n, x ...
- hihocoder 1176
hihocoder 1176 题意:N,M.分别表示岛屿数量和木桥数量,一笔画 分析:欧拉路问题(给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路) 欧拉路的条件 一个无向 ...
- 【HIHOCODER 1176】 欧拉路·一
描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的角色来到了一个很大的湖边.湖上有N个小岛(编号1..N),以及连接小岛的 ...
- 【[Offer收割]编程练习赛11 C】岛屿3
[题目链接]:http://hihocoder.com/problemset/problem/1487 [题意] 中文题 [题解] 岛屿的数目对应了这个图中联通块的数目; 面积则对应有多少个方块; 周 ...
- [LeetCode] Island Perimeter 岛屿周长
You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represen ...
- [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 ...
- [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 ...
- hihocoder -1121-二分图的判定
hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...
随机推荐
- Spring MVC MultiActionController example
In Spring MVC application, MultiActionController is used to group related actions into a single cont ...
- CABasicAnimation精讲
前言 本教程写了这个效果图的demo,同时总结CABasicAnimation的使用方法. 看完gif动画完,看到了什么?平移.旋转.缩放.闪烁.路径动画. 实现平移动画 实现平移动画,我们可以通过t ...
- WEB安全之威胁解析
本文章转载自 http://www.xuebuyuan.com/60198.html 主要威胁: 暴力攻击(brute-force attack):这些攻击通过尝试所有可能的字符组合,以发现用户证书. ...
- UVa 10900 So you want to be a 2n-aire? (概率DP,数学)
题意:一 个答题赢奖金的问题,玩家初始的金额为1,给出n,表示有n道题目,t表示说答对一道题目的概率在t到1之间,每次面对一道题,可以选择结束游戏, 获得当 前奖金:回答下一道问题,答对的概率p在t到 ...
- Windows xp下IDT Hook和GDT的学习
一.前言 对于IDT第一次的认知是int 2e ,在系统调用的时候原来R3进入R0的方式就是通过int 2e自陷进入内核,然后进入KiSystemService函数,在根据系统服务调用号调用系统服 ...
- ibatis 搭建总结
一.搭建ibatis环境 1.导入ibatis的jar包,已及数据库驱动jar包ibatis-2.3.0.677.jar ibatis-dao-2.jar ibatis-sqlmap-2.jar ib ...
- Win7激活后添加grub引导Linux最简单方法
因为Win7(Vista同理)的激活方式是通过grub摸你OEM的Slic信息,所以主引导分区MBR被这个grub占用,以此才能激活WIn7.但是如果想同时安装Linux在别的分区,就会产生问题:gr ...
- [置顶] VC++界面编程之--自定义CEdit(编辑框)皮肤
自定义编辑框是登陆界面经常用到的效果,所以我也模仿站酷网的素材做了个. 要想继承CCustomDraw来完全自绘CEdit控件,是不太可行的方案,因为一旦你完全重绘,那么你需要额外做以下几件事: 1. ...
- Servlet---JavaWeb技术的核心基础,JavaWeb框架的基石(二)
一.Servlet之Request Web服务器会对收到的每一次客户端http请求分别创建一个用于代表请求的request对象和代表响应的response对象.要获取客户端提交的数据需 ...
- iOS开发——网络编程Swift篇&(五)同步Post方式
同步Post方式 // MARK: - 同步Post方式 func synchronousPost() { //创建NSURL对象 var url:NSURL! = NSURL(string: &qu ...