AcWing 1402.星空之夜

考点:Flood Fill 、 哈希 、 BFS  、 DFS 

夜空深处,闪亮的星星以星群的形式出现在人们眼中,形态万千。

一个星群是指一组非空的在水平,垂直或对角线方向相邻的星星的集合。

一个星群不能是一个更大星群的一部分。

星群可能是相似的。

如果两个星群的形状、包含星星的数目相同,那么无论它们的朝向如何,都认为它们是相似的。

通常星群可能有 88 种朝向,如下图所示:

现在,我们用一个二维 0101 矩阵来表示夜空,如果一个位置上的数字是 11,那么说明这个位置上有一个星星,否则这个位置上的数字应该是 00。

给定一个夜空二维矩阵,请你将其中的所有星群用小写字母进行标记,标记时相似星群用同一字母,不相似星群用不同字母。

标注星群就是指将星群中所有的 11 替换为小写字母。

输入格式

第一行包含一个整数 WW,表示矩阵宽度。

第二行包含一个整数 HH,表示矩阵高度。

接下来 HH 行,每行包含一个长度为 WW 的 0101 序列,用来描述整个夜空矩阵。

输出格式

输出标记完所有星群后的二维矩阵。

用小写字母标记星群的方法很多,我们将整个输出读取为一个字符串,能够使得这个字符串字典序最小的标记方式,就是我们想要的标记方式。

输出这个标记方式标出的最终二维矩阵。

数据范围

0≤W,H≤1000≤W,H≤100,
0≤0≤ 星群数量 ≤500≤500,
0≤0≤ 不相似星群数量 ≤26≤26,
1≤1≤ 星群中星星的数量 ≤160≤160

输入样例:

23
15
10001000000000010000000
01111100011111000101101
01000000010001000111111
00000000010101000101111
00000111010001000000000
00001001011111000000000
10000001000000000000000
00101000000111110010000
00001000000100010011111
00000001110101010100010
00000100110100010000000
00010001110111110000000
00100001110000000100000
00001000100001000100101
00000001110001000111000

输出样例:

a000a0000000000b0000000
0aaaaa000ccccc000d0dd0d
0a0000000c000c000dddddd
000000000c0b0c000d0dddd
00000eee0c000c000000000
0000e00e0ccccc000000000
b000000e000000000000000
00b0f000000ccccc00a0000
0000f000000c000c00aaaaa
0000000ddd0c0b0c0a000a0
00000b00dd0c000c0000000
000g000ddd0ccccc0000000
00g0000ddd0000000e00000
0000b000d0000f000e00e0b
0000000ddd000f000eee000

样例解释

样例对应的星空图如下:

答案对应的标记后星空图如下:

题目简述

给定一个二维矩阵,其中有八连通的连通块,识别连通块,并把所有形状相同的连通块用同一个字母标记出来

注:四连通:有公共边才算联通(上下左右); 八连通:只要有公共点就算连通(上下左右、对角线)

思路:

从左上角开始扫描,如果扫描到连通块,看之前是否出现过相同的连通块,如果出现过,就用之前的字母表示这个连通块,如果是一个全新的连通块,就用下一个字母来表示它(从a开始)

1. Flood Fill 算法 可以用来找所有连通块

2. 判断形状是否相似(可通过翻转、旋转、对称把两个图形变为完全相同)

整个矩阵空间是非常庞大的,但是实际存在“星云”的地方是很小的,因此我们想到可以定义一个哈希函数(哈希),将每个不同的块,映射成不同的数字,形状相似的块映射到同一个数

①哈希值与方向无关(将八种不同的方向全部变为一个数)

②尽量避免冲突

构造方法:(很难想)

将一个块中的所有格子找出来,放到一个集合里,用C(n,2) 算它们两两之间的直线距离之和(欧几里得距离之和),把两两欧几里得距离相加,作为哈希值。

可以发现,这样构造,哈希值与方向是无关的

注:在搜每个连通块时,为了方便算哈希值同时为了把每个1变成字母,我们可以用一个数组来存一下块中的所有点。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath> //计算距离,涉及到开根号#define x first
#define y secondusing namespace std;
//用pair来存坐标
typedef pair<int,int> PII;const int  N = 110;
const double eps = 1e-6;int n,m;
char g[N][N]; //g数组存储地图
PII q[N*N]; //连通块中所有点用q来表示,点数最多时N^2
int top; //表示当前连通块中点数//求两个点欧几里得距离
double get_dist(PII a,PII b)
{double dx = a.x - b.x; //横坐标之差double dy = a.y - b.y; //纵坐标之差return sqrt(dx*dx + dy*dy);
}//求哈希值
double get_hash()
{double sum = 0;//枚举两点间的距离C(n,2)for(int i = 0; i < top; i ++ )for(int j = i + 1; j < top; j ++ )sum += get_dist(q[i],q[j]);return sum;
}char get_id(double key)
{//static 可看作全局变量,每次调用函数时数组不会重新分配static double hash[30]; //存储当前已经出现过的哈希值,一共26个字母,这里开到30static int id = 0;for(int i = 0; i < id; i ++ )if(fabs(hash[i] - key) < eps) //如果前面出现过key(比较两个浮点数是否相同)return i + 'a'; //返回第i个字母hash[id ++ ] = key; //把key存成一个新的字母return id - 1 + 'a';
}//flood-fill
void dfs(int a,int b)
{q[top ++ ] = {a,b};g[a][b] = '0'; //标记当前点已被走过//枚举a,b所有邻点for (int x = a - 1; x <= a + 1; x ++ )for (int y = b - 1; y <= b + 1; y ++ ){if(x == a && y == b) continue; //中心点 跳过if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == '1') //判断是否出界,可走dfs(x,y);}
}
int main()
{cin >> m >> n; //读入列数、行数for(int i = 0; i < n; i ++ ) cin >> g[i]; //读入整张图//枚举每一个格子for(int i = 0; i < n; i ++ )for(int j = 0; j < m; j ++ )if(g[i][j] == '1') //如果当前格子里是1{top = 0;   //清空连通块中的所有点dfs(i,j);  //搜索当前整个连通块char c = get_id(get_hash());//找到当前连通块用哪个字母来表示(找到当前连通块的id,输入的值是当前连通块的哈希值)//将当前连通块中的所有点,标记为cfor(int k = 0; k < top; k ++ )g[q[k].x][q[k].y] = c;}for(int i = 0; i < n; i ++ ) cout << g[i] << endl;return 0;}

T Day-1 星空之夜相关推荐

  1. AcWing 1402. 星空之夜 1月28

    AcWing 1402. 星空之夜 1月28 题意: 一个星群是指一组非空的在水平,垂直或对角线方向相邻的星星的集合. 一个星群不能是一个更大星群的一部分. 星群可能是相似的. 如果两个星群的形状.包 ...

  2. 寒假每日一题(提高组)【Week 1 完结】

    目录 1402. 星空之夜[dfs + 哈希] 479. 加分二叉树[DP] 1414. 牛异或[trie] 1402. 星空之夜[dfs + 哈希] https://www.acwing.com/p ...

  3. 华为让爱成双活动,缤纷好礼回馈消费者

    2月2日,华为举办的"让爱成双"活动,不仅在服务APP推出互动小游戏.抖音平台小视频等众多新玩法.同时,华为商城和各大电商平台华为旗舰店还带来多重超值福利活动.即便消费者足不出户, ...

  4. html爱情表白神器,回忆纪念册(附源码)

    文章目录 1.设计来源 1.1 主界面 1.2 相关界面 2.效果和源码 2.1 动态效果 2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/wei ...

  5. 2.14调情方案之个性情人节

    他们说:"情人的眼里容不下沙子." 我们说:"情人的眼里只有彼此." 在2.14这样的日子,放下平日的矜持与羞涩,放松自己的心灵与肌体,来吧,和你的情人调调情, ...

  6. “机器人之夜”看猎豹跑得快还是五款机器人价格降得快?“鸿门宴”正式上演

    来源:机器人大讲堂 3 月 21 日,猎豹移动(NYSE: CMCM)联合旗下人工智能公司猎户星空在北京水立方举行"猎豹3.21机器人之夜"发布会,发布自主研发的猎户机器人平台Or ...

  7. 用python画梵高星空-python 梵高

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 对于一个视频来说,只需要将每一帧都转换后输出,并按照一定的时间间隔清屏. ...

  8. 千灯照碧云,越夜越星沙

    (题图摄影:邓建辉) 文 | 弘乐.陈曦 来源 | 螳螂财经(ID:TanglangFin) "晚上去红记吃小龙虾啊!"准备下班的李强拿着电话呼朋唤友.和他一起下楼的同事伍娟听到了 ...

  9. matlab模拟三体运动_从灯泡到超级计算机,如何模拟浩瀚星空?| 赛先生

    天文学家中有这样一群人,他们既不观星,也不刷公式,而是通过模拟来研究浩瀚星空.在星团.星系这样的恒星系统中,往往包含着上百万颗恒星,规模如此惊人的恒星系统该如何处理?本期"赛先生天文&quo ...

  10. 4月24日云栖精选夜读 | 阿里云POLARDB如何助力轻松筹打造5亿用户信赖的大病筹款平台?...

    [点击订阅云栖夜读周刊] 轻松筹首创了"大病救助"模式,帮助了众多病患在第一时间解決了医疗资金等问题,为了从源头解决了医疗资金问题.而在轻松筹这样全球5.5亿用户信赖的大病筹款平台 ...

最新文章

  1. Storm并行度详解
  2. 搭建一个日常好用的linux系统
  3. #转载#记录:文献阅读第一利器:文献笔记法(Literature Notes)
  4. tl494c封装区别_TL494参数,功能介绍,TL494应用电路图,封装,管脚及TL494 PDF中文资料手册...
  5. 鸿蒙历程及路标没有适配手机,鸿蒙2.0来了?华为开发者大会时间确认:Mate40会不会首发?...
  6. 面向对象的Oracle用法
  7. linux 移出权限,如何在 Ubuntu 上为用户授予和移除 sudo 权限
  8. php tp3.2 脚本大量数据操作思路
  9. jquery.nicescroll.min.js滚动条插件的用法
  10. oracle mysql 中文排序规则_Oracle 对汉字的order by排序规则
  11. 信息完全技术之Enigma密码机【MATLAB程序及软件APP实现】
  12. 性能测试场景设计深度解析
  13. 港科夜闻|全国政协副主席梁振英一行到访香港科技大学(广州)
  14. 单片机计数器实验代码c语言,单片机计数器功能实验程序
  15. 华为、阿里、腾讯、百度、360,不能再打了。
  16. 联通研究院注重自主研发能力提升, 3人荣获CKA认证
  17. 【转载】生活常识,人人必备
  18. 2023寒假集训通知
  19. AD快捷键笔记(画板前一定要看看)
  20. Rascal Flatts乐队简介

热门文章

  1. java烟花代码详细步骤,一文说清!
  2. 元转万元单位换算_度数单位换算(元换算成万元换算器)
  3. [国家集训队]Tree I
  4. 欧姆龙的PLC的FINS通讯协议的C例子
  5. Android多开检测的另一个思路
  6. 实战ASP.NET访问共享文件夹
  7. Linux必会的rpm命令安装软件
  8. 练习java文档Matcher
  9. #今日论文推荐# XAI+网络安全?布兰登大学等最新《可解释人工智能在网络安全应用》综述,33页pdf阐述其现状、挑战、开放问题和未来方向
  10. 信息收集(部分,不全面)