POJ 3349 - 数值哈希(这辈子只服数据量)
来源:互联网 发布:淘宝帐号可以注销吗 编辑:程序博客网 时间:2024/05/22 08:21
1.Question:
题意描述:
输入:n代表有多少片雪花
之后的n行,每行6个数字代表雪花的6个枝杈的长度(正序逆序都可以)
输出:
如果以上的雪花中出现了同构的情况,那么我们认为出现了相同的雪花
最后如果我们认为有两种相同的雪花,输出Twin snowflakes found.
否则输出No two snowflakes are alike.
2.Solution:
本题的数据量是我最想吐槽的,而不能提的思路是哈希(为了优化速度,不然铁定超时)
1.朴素思路:
如果我们采用数组直接存储的话,对于每一中的情况我们都需要进行往前的回溯判断,总共需要
T(n)=1+2+...+n=O(n^2)的时间复杂度,本题来说的话10000^2是一定会超时的,在这里我们就要考虑优化了
2.优化思路1:
我们这里哈希的本质思路是对雪花进行分类,我们分类的依据是六个分叉的和相同的试做一个类,这样的话,我们对雪花进行分类之后可以通过(类似邻接表的思路)快速的减少遍历的次数来进行快速的正确的判断,如果数据哈希的均匀的话,可以无限接近于O(1)
3.TLE+RE的教训
首先我们来说说RE,在本题中因为我多次的TLE之后让我误以为是散列的范围不够大,所以我将哈希函数改成平方和对10w取模,但是在计算的过程之后发现TLE变成了RE,在这里我认为是因为本题的数据量有点大在100w的数据平方之后导致对于long型数据也溢出了,所以我们最好不要采用平方和的哈希方案
对于TLE有这么几点:
1.首先,我们的不要用线性探测的思路去做,因为线性探测是会出现二次聚集的情况的,我们最好的思路是采用拉链法构建哈希表
2.本题的用平方和的思路是可以做的,但是要求我们对结果要不断的取模控制溢出,但是这里也就引入了驱魔运算的效率的问题,我们都知道木偶运算是非常的低效的,索引说对于大数量的取模操作耗时也是让我们在本体的数据量下变得难以接受
3.最后,也是最重要的一点,我们千万不要为了节约内存对节点的保存数组用int*指针来代替,在用的时候我们动态分配内存的时间是非常的恐怖的,这也就是我TLE的根本所在
ps:本题判断雪花是不是相同的,我们采用了一点点优化,我摘引自别的大神,其他的判断方式当然也可以,但是这样写的非常的直观
3.Code:
/*Problem: 3349User: lantianheyeqiMemory: 8908KTime: 3485MSLanguage: G++Result: Accepted*/#include"iostream"#include"cstdio"#include"cstdlib"#include"cstring"#define N 100001using namespace std;typedef struct node{int data[6];struct node* last;}point;int n;point snow[N];int dp[6];void init(){for(int i=0;i<N;i++) snow[i].last=NULL;}bool issame(int* white){for(int i=0;i<6;i++) //这里为了解决同构的问题,我们必须要考虑顺时针和逆时针,在这里我们引入了如下的方法进行优化,值得学习 {if((dp[0]==white[i]&& dp[1]==white[(i+1)%6]&& dp[2]==white[(i+2)%6]&& dp[3]==white[(i+3)%6]&& dp[4]==white[(i+4)%6]&& dp[5]==white[(i+5)%6]) || (dp[0]==white[i]&& dp[1]==white[(i+5)%6]&&dp[2]==white[(i+4)%6]&&dp[3]==white[(i+3)%6]&&dp[4]==white[(i+2)%6]&&dp[5]==white[(i+1)%6]))return true;}return false;}bool find(int key){point* k=snow[key].last;while(k!=NULL){if(issame(k->data)) return true;k=k->last;}return false;}void insert(int key){point* k=new point;for(int i=0;i<6;i++) k->data[i]=dp[i];k->last=snow[key].last;snow[key].last=k;}int main(){bool ok=false;init();scanf("%d",&n);for(int i=1;i<=n;i++){int sum=0;for(int j=0;j<6;j++) scanf("%d",&dp[j]),sum+=dp[j];sum=sum%N;if(find(sum)) ok=true;else insert(sum);}if(ok) printf("Twin snowflakes found.\n");else printf("No two snowflakes are alike.\n");return 0;}
1 0
- POJ 3349 - 数值哈希(这辈子只服数据量)
- 这辈子,只和老婆做的50件事
- 这辈子只跟老婆做的50件事
- 这辈子
- 这辈子
- 如果你这辈子只做一次这种心理测试,就请做这个吧
- 这辈子,下辈子
- 男人这辈子
- 1月10日(这辈子永远的痛)
- 我们的爱、相约在下辈子。这辈子、记得忘了我、(看完我哭了、一定要看)
- 这辈子要读一遍的书
- 我这上半辈子(写在即将到来的27周岁)
- 男人这辈子挺难的(好女人一定要看看)
- 搜集的各种推荐书籍(不晓得这辈子读得完不!)
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(一)
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(二)
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(一)
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(完)
- 搞懂JAVA集合类--线程安全问题(六)
- MPAndroidChart 教程:图表的具体设置 Specific chart settings(六)
- MapReduce 基本模版与WordCount代码
- map集合遍历
- Acticle 18:jquery基础(基本选择器)具体实例
- POJ 3349 - 数值哈希(这辈子只服数据量)
- 验证整数、小数、实数、有效位小数最简单JavaScript正则表达式
- Hiveserver2 beeline error java.io.FileNotFoundException: minlog-1.2.jar
- 在windows下将Mongodb注册为服务,报错
- MPAndroidchart 教程:图例 Legend(七)
- Two Sum (LeetCode OJ)
- 关于小程序请求接口报400的问题
- Spring学习笔记
- 详解javascript的类