哈希表模板题,因为相同雪花的长度相同,顺序不一样,那么相同雪花的累加和累乘相等。利用这个性质可以用哈希表将雪花分类。之后再分类查找。
这样设计哈希函数:(长度累加+长度累乘)%P,这个P是接近N的一个质数,这样可以使得哈希表尽量分散。
然后就是查找,判断是否是同一片雪花。
这道题居然卡了stl,用list交T了好几次,手写链表才能过,POJ真的很严格。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <list> using namespace std; typedef long long LL; int n,s[100010][6],P=99991,tot=0,head[100010]; struct List{ int *snow; int nxt; }li[100010]; int Hash(int *x) { int sum=0,mul=1; for(int i=0;i<6;i++) { sum=((LL)sum+x[i])%P; mul=((LL)mul*x[i])%P; } return (sum+mul)%P; } bool Equal(int *a,int *b) { for(int i=0;i<6;i++) { for(int j=0;j<6;j++) { bool eq=true; for(int k=0;k<6;k++) if(a[(i+k)%6]!=b[(j+k)%6]) eq=false; //同方向枚举判断是否是同一片雪花 if(eq==true) return true; eq=true; for(int k=0;k<6;k++) if(a[(i+k)%6]!=b[(j-k+6)%6]) eq=false; // 反方向枚举 if(eq==true) return true; } } return false; } bool Insert(int *x) { int ha=Hash(x); for(int i=head[ha];i;i=li[i].nxt) { if(Equal(li[i].snow,x)) return false; } tot++; li[tot].snow=x; li[tot].nxt=head[ha]; head[ha]=tot; return true; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=0;j<6;j++) scanf("%d",&s[i][j]); if(!Insert(s[i])) { printf("Twin snowflakes found. "); return 0; } } printf("No two snowflakes are alike. "); return 0; }