题意:
给你n片雪花,每片雪花有六个角,每个角的形状以一个数字表示(≤1e7),让你判断是否存在有两片雪花一模一样
判等当且仅当:
从任意一个角顺时针或逆时针数字完全相符
若有,输出:Twin snowflakes found.
若无,输出:No two snowflakes are alike.
Sample Input
2
1 2 3 4 5 6
4 3 2 1 6 5
Sample Output
Twin snowflakes found.
思路:
最基本的 hip hop,H(snow) = 六个数字的乘积 + 六个数字的总和(应该不会冲突吧……)
每有一个 val 不同的雪花,我们通过邻接表存储
如果 val 相同了,我们再判断顺序是否相同,有些暴力,但好在数据小
就好啦~
Hash 注意开 long long
code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int P=99991,MXN=110000; int n,cnt,next[MXN],head[MXN],snow[MXN][6]; int Hash(int *a) { int sum=0,mul=1; for(int i=0;i<6;++i) { sum=(sum+a[i])%P; mul=(long long)mul*a[i]%P; } return (sum+mul)%P; } bool equ(int *a,int *b) { for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { bool flag=1; for(int k=0;k<6;++k) { if(a[(i+k)%6]!=b[(j+k)%6]) { flag=0;break; } } if(flag) return 1; flag=1; for(int k=0;k<6;++k) { if(a[(i+k)%6]!=b[(j-k+6)%6]) { flag=0;break; } } if(flag) return 1; } } return 0; } bool inser(int *a) { int val=Hash(a); for(int i=head[val];i;i=next[i]) { if(equ(a,snow[i])) return 1; } ++cnt; memcpy(snow[cnt],a,6*sizeof(int)); next[cnt]=head[val]; head[val]=cnt; return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) { int t[6]; for(int i=0;i<6;++i) { scanf("%d",&t[i]); } if(inser(t)) { printf("Twin snowflakes found."); return 0; } } printf("No two snowflakes are alike."); return 0; }