#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int MAXHASH = 100003; bool vis[MAXHASH]; bool ok; int state[MAXHASH][6];//存放雪花形状的状态 int head[MAXHASH],next[MAXHASH]; int n; unsigned int hash(int st[])//求和取模的哈希函数 { unsigned int h = 0; for(int i = 0;i < 6;++i) h += st[i]; return h % MAXHASH; } void checkCollision(int h)//检测冲突 { for(int i = head[h];i != -1;i = next[i])//枚举 { for(int j = next[i];j != -1;j = next[j]) { int a[6],b[6];//一个正时钟方向,一个逆时钟方向 for(int k = 0;k < 6;++k) { for(int x = k,y = 0;y < 6;++y,++x)//枚举12种旋转方式 a[y] = state[i][x % 6]; memcpy(b,a,sizeof(a)); reverse(b,b + 6);//反向 if(memcmp(a,state[j],sizeof(a)) == 0)//如果在哈希链表中发现相同的,则说明有冲突 { ok = 0; return; } if(memcmp(b,state[j],sizeof(b)) == 0) { ok = 0; return; } } } } } int main() { //freopen("in.txt","r",stdin); scanf("%d",&n); memset(head,-1,sizeof(head)); ok = 1; int st[6]; for(int i = 1;i <= n;++i) { for(int j = 0;j < 6;++j) scanf("%d",&state[i][j]); int h = hash(state[i]); next[i] = head[h];//逆序插入哈希表头 head[h] = i; } for(int h = 0;h < MAXHASH;++h) { if(!ok) break; if(head[h] != -1)//如果哈希表头不为空 checkCollision(h);//检测冲突 } if(ok) printf("No two snowflakes are alike./n"); else printf("Twin snowflakes found./n"); return 0; }