AcWing 137 雪花雪花雪花(初探hash)

题目链接

解题思路

  本题的数据范围显然不能把所有数组一个一个对比,可以建立一个哈希表,不同的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;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/13336743.html