原来看到过字符串hash
这次碰到了一个数值型hash就在比赛的时候放弃了,果然还是太弱,需要多学习
暴力的话,n平方的算法,而且需要顺时针和逆时针判断12次,肯定TLE
暴力不行才会需要想别的方法:
对所有的值进行HASH是分了对值进行分类,分类最正常也是最一般的想法就是%一个质数
质数选择很重要:几万左右的比较好
如果在一组的话,那么就使用暴力匹配,顺时针和逆时针判断12次,如果至少有1次匹配成功就说明正确
否则,当所有数据读完之后都没有,那就是没有结果
#include<map> #include<set> #include<math.h> #include<time.h> #include<iostream> #include<cstdio> #include<queue> #include<stack> #include<stdio.h> #include<cstring> #include<string.h> #include<algorithm> #include<cstdlib> using namespace std; #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define ll rt<<1 #define rr rt<<1|1 #define LL long long #define ULL unsigned long long #define maxnum 1000050 #define eps 1e-6 #define input freopen("input.txt","r",stdin) #define output freopen("output.txt","w",stdout) const int maxn=15000; const int maxm=50; struct node{ int a[6]; }snow[maxn][maxm]; int m[maxn]; int hash(node x){ int key=0; for(int i=0;i<6;i++) key+=x.a[i]; key%=14997; return key; } int cmp(node x,node y){ int st,i,j; for(st=0;st<6;st++){ for(i=st,j=0;j<6;j++,i=(i+1)%6) if (x.a[i]!=y.a[j]) break; if (j==6) return 1; for(i=st,j=0;j<6;j++,i=(i+5)%6) if (x.a[i]!=y.a[j]) break; if (j==6) return 1; } return 0; } int main(){ //input; int i,j,pos,n; node SNOW; scanf("%d",&n); memset(m,0,sizeof(m)); for(i=1;i<=n;i++){ for(j=0;j<6;j++) scanf("%d",&SNOW.a[j]); pos=hash(SNOW); for(j=0;j<m[pos];j++){ if (cmp(SNOW,snow[pos][j])){ puts("Twin snowflakes found."); return 0; } } snow[pos][m[pos]]=SNOW; m[pos]++; } puts("No two snowflakes are alike."); return 0; }
只要存在一组马上就可以退出返回,不需要继续查询了