数字hash _ 熟练掌握数组当作链表来用的技能
来源:互联网 发布:哪个导航软件最好用 编辑:程序博客网 时间:2024/06/01 09:58
通过这道题要熟练掌握把数组当作链表来用的技能,这和图的邻接表的数组实现及其应用基于同样的原理。
本题题目链接Snowflake Snow Snowflakes
每个雪花都有六个分支,用六个整数代表,这六个整数是从任意一个分支开始,朝顺时针或逆时针方向遍历得到的。输入多个雪花,判断是否有形状一致的雪花存在。
简单的数字哈希,要注意的是每种雪花可以由多种数字组合表示。
比如输入的是1 2 3 4 5 6,
则2 3 4 5 6 1,3 4 5 6 1 2,……,6 5 4 3 2 1,5 4 3 2 1 6等都是相同形状的。
原文是(因此可以在读入一个雪花的时候把这些情况全部放入哈希表中)
但我给改成只插入一次雪花,而非12次。
如果某次插入的时候存在重复的雪花,那么后面的不需要再处理。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N = 100001; const int H = 100001; typedef struct node{int arm[6];int next; //记录同哈希值的雪花的上一编号 }Node; Node node[N];int counter; //雪花编号,一直是累加的 int hashtable[H];void initial_hash(){ counter=0;for(int i=0;i<H;i++){hashtable[i]=-1; //前继无人 }}bool compare(int *arm1,int *arm2){ for (int i = 0; i < 6; ++i) { if (arm1[i] != arm2[i]) return false; } return true; } unsigned get_hash(int *arm){unsigned int total=0;for(int i=0;i<6;i++){total+=arm[i];}return total % H;}void insert(int *arm,unsigned int h){for(int i=0;i<6;i++){node[counter].arm[i]=arm[i];}node[counter].next=hashtable[h];hashtable[h]=counter++; //counter是雪花编号,一直是累加的 }bool search(int *arm){int h=get_hash(arm);for(int i=hashtable[h];i!=-1;i=node[i].next){if(compare(node[i].arm,arm)) return true;} /* 把这句挪到主函数中的循环匹配函数后,只有在匹配失败后才插入; 否则按照原来的写法,需要插入12次同样的雪花 insert(arm,h); */return false;}int main() { int arm[2][11]; //不用12列,只用11列就够了 int n; bool twin = false; initial_hash(); scanf("%d", &n); while (n--) { for (int i = 0; i < 6; ++i) { scanf("%d", &arm[0][i]); arm[0][i + 6] = arm[0][i]; } if (twin) continue; //已经匹配了之后,就不管后面的输入了 for (int i = 0; i < 6; ++i) { arm[1][i + 6] = arm[1][i] = arm[0][5 - i]; } /*上面两个for循环是为了处理所有的雪花情况——顺时针、逆时针、错位等,共12种情况*/ int i; for ( i = 0; i < 6; ++i) { //每一种情况(雪花的旋转)都要search,每一次search都有不定数量的compare(和同组相同哈希值的雪花进行比较) //相同的hash值不意味着雪花相等,敌不动我动,只有待插入(比较)的雪花才旋转,已经插入的不动,等待比较 if (search(arm[0] + i) || search(arm[1] + i)) { twin = true; break; } } if(i==6) { //没找到才插入一次(最原始的雪花) insert(arm[0],get_hash(arm[0])); } } if (twin) printf("Twin snowflakes found.\n"); else printf("No two snowflakes are alike.\n"); return 0; }
0 0
- 数字hash _ 熟练掌握数组当作链表来用的技能
- Excel 有哪些可能需要熟练掌握而很多人不会的技能?
- 【SQL】练习并熟练掌握用T-SQL查询命令进行数据查询的技能【原创技术】
- 【SQL】练习并熟练掌握用T-SQL查询命令进行数据查询的技能【原创技术】
- Excel 熟练操作不为人知的技能
- DBA掌握的技能
- 掌握的技能
- 掌握的技能
- 应该熟练掌握的常用的算法
- java程序员要熟练掌握的知识
- 字符串转换 - 应该熟练掌握的东西
- 要熟练掌握的七个人生工具
- 要熟练掌握的七个人生工具
- JVM需要熟练掌握的知识点
- 熟练掌握人生的七种工具
- JVM需要熟练掌握的知识点
- 作为一个Java程序员应该熟练掌握这10项技能
- 软件工程师应该掌握的技能
- Java Socket编程 文件传输(客户端从服务器下载一个文件)
- Memcache 优化建议
- Java JVM
- public,protected,private
- 全局变量、有效域、命名空间
- 数字hash _ 熟练掌握数组当作链表来用的技能
- Linux程序设计(Linux shell编程十四)
- Xcode 自定义快捷键 - 剪切当前行
- hdu1421--搬寝室(01背包)
- Objective-C浮点数转化整数(向上取整、向下取整)
- index_04_01底部
- 华为2015年实习招聘机试
- java Socket通信(一)
- VC如何用代码实现选中某一行并高亮