有N片雪花,每片雪花由六个角组成,每个角都有长度。

第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,…,ai,6ai,1,ai,2,…,ai,6。

因为雪花的形状是封闭的环形,所以从任何一个角开始顺时针或逆时针往后记录长度,得到的六元组都代表形状相同的雪花。

例如ai,1,ai,2,…,ai,6ai,1,ai,2,…,ai,6和ai,2,ai,3,…,ai,6,ai,1ai,2,ai,3,…,ai,6,ai,1就是形状相同的雪花。

ai,1,ai,2,…,ai,6ai,1,ai,2,…,ai,6和ai,6,ai,5,…,ai,1ai,6,ai,5,…,ai,1也是形状相同的雪花。

我们称两片雪花形状相同,当且仅当它们各自从某一角开始顺时针或逆时针记录长度,能得到两个相同的六元组。

求这N片雪花中是否存在两片形状相同的雪花。

输入格式

第一行输入一个整数N,代表雪花的数量。

接下来N行,每行描述一片雪花。

每行包含6个整数,分别代表雪花的六个角的长度(这六个数即为从雪花的随机一个角顺时针或逆时针记录长度得到)。

同行数值之间,用空格隔开。

输出格式

如果不存在两片形状相同的雪花,则输出:

No two snowflakes are alike.

如果存在两片形状相同的雪花,则输出:

Twin snowflakes found.

数据范围

1≤n≤100000
0≤ai,j<100000000

输入样例:

2
1 2 3 4 5 6
4 3 2 1 6 5

输出样例:

Twin snowflakes found.

 题解: 定义哈希 Hash 函数 H(a[i] ) = ( 

Acwing - 137 雪花雪花雪花_#define

 + 

Acwing - 137 雪花雪花雪花_#define_02

 ) mod p  , p 是一个大质数. 显然对于两片雪花 ,他们的六个角的长度之和,长度之积相等, 因此 hash 值也相同 . 

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Swap(a,b) a ^= b ^= a ^= b
#define pi acos(-1)
#define cl(a,b) memset(a,b,sizeof(a))
using namespace std ;
const int MAX = 100010 ;
const int inf = 0x3f3f3f3f ;
int n ;
int tot ;
typedef long long LL ;
const int p = 1e9+7 ;
int snow[MAX][6] ;
int head[MAX] ;
int next[MAX] ;
LL H(int *a){ // 一组雪花的hash 值
LL sum = 0 ,mul = 1 ;
for(int i = 0 ; i<6 ; i++ ) {
sum = (sum+a[i])%p ;
mul = (mul*a[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 = 1 ;
for(int k = 0 ;k<6 ; k++ ) { // 顺序比较
if(a[(i+k)%6] !=b[(j+k)%6]){
eq = 0 ;
}
}
if(eq ) return 1 ;
for(int k = 0 ; k<6 ;k++ ) { // 逆序比较
if(a[(i+k)%6] !=b[(j-k+6)%6]){
eq = 0 ;
}
}
if(eq) return 1 ;
}
}
}
bool insert(int *a){
LL val = H(a) ;
// 从hash 值为 val 的链开始搜素该链,看是否有相同的 ,
for(int i = head[val] ; i;i = next[i]) {
if(equal(snow[i],a)){
return 1 ;
}
}
// 没有相同的就插入
++tot ;
memcpy(snow[tot],a,6*sizeof(int)) ;
next[tot] = head[val] ;
head[val] = tot ;
return 0 ;
}
int main()
{
cin >> n ;
for(int i = 1 ; i<=n ; i ++ ) {
int a[10] ;
for(int j = 0 ; j<6 ; j++) {
scanf("%d",&a[j]);
}
if(insert(a)){
puts("Twin snowflakes found.");
return 0;
}

}

puts("No two snowflakes are alike.") ;

return 0 ;
}