hash表

hash表

Snowflake Snow Snowflakes

有n片雪花,每片雪花有六个角,六个角的角度从顺时针依次记为\(a_1,a_2....a_6\) 判断两片雪花是否相同的依据是 从任何一个角开始顺时针或者逆时针往后记录角度,得到的六元组相等的话,就代表雪花相同,例如\(a_1, a_2...a_6\)\(a_2,a_3...a_1\) 相等的话,两片雪花相同。\(a_1,a_2...a_6\)\(a_6,a_5...a_1\) 相等的话,两片雪花相同。

题解:

定义hash函数,H(\(a_1,a_2...a_6\)) = (\(\sum_{i = 1}^{6} a_i + \prod_{i =1}^{6} a_i\)) % mod;(其中mod是我们定义的质数)

建立一个hash表,把n片雪花依次插入,对于每片雪花,我们直接扫描表头H对应的链表,检查是否存在相同的雪花即可。

具体看代码,还是比较简单易懂的

#include <cstdio>
int head[100010], snow[100010][10], next[100010], mod = 99991, cnt;
bool equaln(int *a, int *b) {
    for(int i = 0; i < 6; i++) {
        int flag = 0;
        for(int j = 0; j < 6; j++) {
            if(a[(i+j) % 6] != b[j]) {
                flag = 1;
                break;
            }
        }
        if(!flag) return true;
        flag = 0;
        for(int j = 5; j >= 0; j--) {
            if(a[(i+j) % 6] != b[5-j]) {
                flag = 1;
                break;
            }
        }
        if(!flag) return true;
    }
    return false;
}
bool insertn(int *a) {
    long long sum = 0, mul = 1, val = 0;
    for(int i = 0; i < 6; i++) {
        sum = (sum + a[i]) % mod;
        mul = (mul * a[i]) % mod;
    }
    val = (sum + mul) % mod;
    for(int i = head[val]; i; i = next[i]) {
        if(equaln(snow[i], a)) return true;
    }
    cnt++;
    for(int i = 0; i < 6; i++) {
        snow[cnt][i] = a[i];
    }
    next[cnt] = head[val];
    head[val] = cnt;
    return false;
}
int main() {
    int n, f = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        int a[10];
        for(int j = 0; j < 6; j++) {
            scanf("%d", &a[j]);
        }
        if(insertn(a)) {
            f = 1;
        }
    }
    if(f == 1) printf("Twin snowflakes found.\n");
    else printf("No two snowflakes are alike.\n");
    return 0;
}

posted @ 2020-04-19 20:57  小饭hhh  阅读(112)  评论(0编辑  收藏  举报