优化哈希了大半天,总想着避免冲突,结果冲突没解决,最后发现哈希的姿势是错的。。。
果然相对于学长讲的内容,还是老师更靠谱,在很多情况下想要避免哈希冲突很难,不如存储冲突元素再遍历。
这个题,即使我一开始的哈希是对的,由于哈希映射空间不是那么大,必须采用几个数字作为进制哈希才比较靠谱,那样也会增大时间开销,更何况这道题进制哈希很麻烦。
题意:
每个雪花有六个角,每个角一个长度,给你n个雪花的信息(顺时针或逆时针从任意一个角开始),判断是否存在两个雪花相同。
Input
The first line of input will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.
Output
If all of the snowflakes are distinct, your program should print the message:
No two snowflakes are alike.
If there is a pair of possibly identical snow akes, your program should print the message:
Twin snowflakes found.
由于难以进制哈希,直接把雪花所有角无顺序哈希成一个数,我最终AC的代码采用的是直接求和,然后对每个哈希值,开一个链表记录哈希空间下的雪花,每次哈希完,和相同哈希值下的所有雪花比较,注意比较时要从两个方向、任意角开始。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define mod 999983
#define mxn 100010
struct flake{
int a[6];
flake* nxt;
flake(){nxt=NULL;}
}f[mxn];
struct hash_table{
flake* first;
hash_table(){first=NULL;}
}hash[mod];
int n;
int hashing(flake in){
int ret=0;
for(int i=0;i<6;++i)
ret=(ret+in.a[i])%mod;
return ret;
}
bool cmp(flake l,flake r){
for(int i=0;i<6;++i){
bool ok=true;
for(int j=0;j<6;++j) if(l.a[j]!=r.a[(j+i)%6]){
ok=false;
break;
}
if(ok) return true;
}
for(int i=0;i<6;++i){
bool ok=true;
for(int j=0;j<6;++j) if(l.a[j]!=r.a[(6-j+i)%6]){
ok=false;
break;
}
if(ok) return true;
}
return false;
}
int main(){
scanf("%d",&n);
bool ans=false;
for(int i=0;i<n;++i){
for(int j=0;j<6;++j)
scanf("%d",&f[i].a[j]);
if(ans) continue;
int tem=hashing(f[i]);
flake* cur=hash[tem].first;
flake* pre=NULL;
while(cur!=NULL){
if(cmp(*cur,f[i])){
ans=true;
break;
}
pre=cur;
cur=cur->nxt;
}
if(!ans){
if(pre==NULL)
hash[tem].first=f+i;
else
(pre->nxt)=f+i;
}
}
if(ans) puts("Twin snowflakes found.");
else puts("No two snowflakes are alike.");
return 0;
}