Snowflake Snow Snowflakes
哈希。首先是哈希函数的选择,先将每组的六个数字进行求和,然后对一个较大的素数取模。在就是判同构的问题,给定两个数字
串,判定是不是循环同构的。因为本题中只有六个,所以我们直接枚举就可以了。
#include <cstdio>
#include <cstring>
#include <vector>
#define maxn 100005
#define mod 10001
int N ;
int num[maxn][6] ;
std::vector<int> v[mod] ;
inline int hash(int x){
return x%mod ;
}
bool judge(int x , int y){
for(int i = 0 ; i < 6 ; i ++){
if(num[x][0] == num[y][i] &&
num[x][1] == num[y][(i+1)%6] &&
num[x][2] == num[y][(i+2)%6] &&
num[x][3] == num[y][(i+3)%6] &&
num[x][4] == num[y][(i+4)%6] &&
num[x][5] == num[y][(i+5)%6]
)
return 1 ;
if(num[x][0] == num[y][i] &&
num[x][1] == num[y][(i+5)%6] &&
num[x][2] == num[y][(i+4)%6] &&
num[x][3] == num[y][(i+3)%6] &&
num[x][4] == num[y][(i+2)%6] &&
num[x][5] == num[y][(i+1)%6]
)
return 1 ;
}
return 0 ;
}
bool check(int x , int y){
for(int i = 0 ; i < v[x].size() ; i ++){
if( judge(v[x][i] , y) )
return 1 ;
}
return 0 ;
}
int main(){
scanf("%d" , &N) ;
int sum ;
bool flag ;
flag = 0 ;
for(int k = 0 ; k < N ; k ++){
scanf("%d%d%d%d%d%d" , &num[k][0] , &num[k][1] , &num[k][2] , &num[k][3] , &num[k][4] , &num[k][5] ) ;
sum = num[k][0] + num[k][1] + num[k][2] + num[k][3] + num[k][4] + num[k][5] ;
sum = hash(sum) ;
flag = check(sum , k) ;
if(flag)
break ;
v[sum].push_back(k) ;
}
if(flag)
printf("Twin snowflakes found.\n") ;
else
printf("No two snowflakes are alike.\n") ;
return 0 ;
}