解题思路
本题的数据范围显然不能把所有数组一个一个对比,可以建立一个哈希表,不同的h[x]代表不同的哈希值,哈希值冲突的数组就存在同一个h[x]开头的链表里,然后根据哈希值来对比对应的字符串,减少重复比较。
代码
const int maxn = 1e5+10;
int a[10], snow[maxn][6], h[maxn], nxt[maxn], tot;
int H() {
//计算哈希值
int sum = 0, mul = 1;
for (int i = 0; i<6; ++i) {
sum += a[i]; mul = (ll)mul*a[i]%MOD;
}
return (sum+mul)%MOD;
}
bool check(int *b) {
//枚举两个数组以i,j为起点的情况
for (int i = 0; i<6; ++i)
for (int j = 0; j<6; ++j) {
bool ok1 = true, ok2 = true;
for (int k = 0; k<6; ++k) {
if (a[(i+k)%6]!=b[(j+k)%6]) ok1 = false; //两个都是顺时针
if (a[(i+k)%6]!=b[(j-k)%6]) ok2 = false; //一顺一逆
}
if (ok1 || ok2) return true;
}
return false;
}
bool insert() {
//判断能否在已经计算过哈希值的数组里面找到a数组
int x = H();
for (int i = h[x]; i; i=nxt[i])
if (check(snow[i])) return true;
//找不到,新建结点
++tot;
memcpy(snow[tot],a,sizeof(int)*6);
nxt[tot] = h[x];
h[x] = tot;
return false;
}
int main() {
int n; scanf("%d",&n);
bool ok = false;
for (int i = 0; i<n; ++i) {
for (int j = 0; j<6; ++j) scanf("%d",&a[j]);
if (insert()) ok = true;
}
printf("%s
", ok ? "Twin snowflakes found.":"No two snowflakes are alike.");
return 0;
}