题目大意:有n个雪花,给出每个雪花六个边的长度,问是否存在两个相同的雪花。
hash函数记为所有边的和就可以,判断时 如果两个hash值相同,那么把雪花做旋转 翻转去比较即可
(实际上比较的部分像我这么写(用sort)是不对的,但AC了也懒得改了···)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <algorithm>
#define ll long long
#define eps 1e-8
#define ms(x,y) (memset(x,y,sizeof(x)))
#define fr(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int M2=999983,maxn=1e6+10;
struct snow
{
int len[7],key;
}p[maxn];
int key1(snow a)
{
int s=0;
fr(i,1,6){s+=a.len[i];s%=M2;}
return s;
}
bool cmp(snow a,snow b){return a.key<b.key;}
bool eq(snow a,snow b)
{
fr(i,1,6)if(a.len[i]!=b.len[i])return 0;
return 1;
}
snow mov(snow a)
{
int t=a.len[6];
for(int i=6;i>=2;i--)a.len[i]=a.len[i-1];
a.len[1]=t;
return a;
}
snow turn(snow a)
{
fr(i,1,3)
swap(a.len[i],a.len[7-i]);
return a;
}
bool is(snow a,snow b)
{
fr(i,1,6)
{
//fr(j,1,6)cout<<a.len[j]<<' ';cout<<endl;
if(eq(a,b))return 1;
a=mov(a);
}
a=turn(a);
fr(i,1,6)
{
//fr(j,1,6)cout<<a.len[j]<<' ';cout<<endl;
if(eq(a,b))return 1;
a=mov(a);
}
return 0;
}
int main()
{
int n;
cin>>n;
fr(i,1,n)
{
fr(j,1,6)scanf("%d",&p[i].len[j]);
p[i].key=key1(p[i]);
}
sort(p+1,p+n+1,cmp);
fr(i,1,n-1)
{
if(p[i].key==p[i+1].key)
{
if(is(p[i],p[i+1])){cout<<"Twin snowflakes found."<<endl;return 0;}
}
}
cout<<"No two snowflakes are alike."<<endl;
return 0;
}