题目链接: https://www.acwing.com/problem/content/139/
可以用Hash的思想,定义Hash函数 H(a1,a2....a6)=(6个数之积+6个数之和)% p;
p是我们自己选取的一个较大的质数,当想知道是否与这片雪花相等时,可以先比较
两片雪花的Hash值,如果Hash值相等,再去看这两片雪花是否真正相等。
期望的时间复杂度为O(N2/p)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<map> using namespace std; const int SIZE=100010; int n,k=0,p=99991,snow[SIZE][6],head[SIZE],net[SIZE]; int fun(int *a) { int sum=0,w=1; for(int i=0; i<6; i++) { sum=(sum+a[i])%p; w=(long long)w*a[i]%p; } return (sum+w)%p; } bool equal(int *a,int *b) { for(int i=0; i<6; i++) { for(int j=0; j<6; j++) { int v=1; for(int h=0; h<6; h++) { if(a[(i+h)%6]!=b[(j+h)%6]) v=0; } if(v==1) return 1; v=1; for(int h=0; h<6; h++) { if(a[(i+h)%6]!=b[(j-h+6)%6]) v=0; } if(v==1) return 1; } } return 0; } bool insert(int *a) { int w=fun(a); for(int i=head[w]; i; i=net[i]) { if(equal(snow[i],a)) return 1; } ++k; for(int i=0;i<6;i++) snow[k][i]=a[i]; net[k]=head[w]; head[w]=k; return 0; } int main() { scanf("%d",&n); int a[10]; for(int i=0; i<n; i++) { for(int j=0; j<6; j++) scanf("%d",&a[j]); if(insert(a)) { printf("Twin snowflakes found. "); return 0; } } printf("No two snowflakes are alike. "); return 0; }