poj3274 hash

来源:互联网 发布:h5斗牛源码网站 编辑:程序博客网 时间:2024/04/18 16:22

怎么hash网上已经说得很清楚,我就不多说了。

我看的这个博客: http://hi.baidu.com/aconly/blog/item/9d1ed1122a29af876538db0b.html

直接贴一下我的代码, 也有一些我做的过程中遇到的问题:

#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define K 33#define N 100005#define SIZE 200003 //tableSize 取满足4 * k + 3的质数,且闭散列使装载因子<=0.5,所以tableSize取总元素个数的2倍int sum[N][K], a[N][K];int hash[SIZE];inline int hashcode(int v[], int k) //网上的hash函数,据说是折叠法{ int val = 0; for (int i = 1; i < k; i++) val = ((val << 2) + (v[i] >> 4)) ^ (v[i] << 10); val = val % SIZE; val = val < 0 ? val + SIZE : val; return val;}int main(){    int n, k, id;    int i, j, r, ans = 0;    scanf("%d %d", &n, &k);    memset(sum[0], 0, sizeof(sum[0]));    memset(hash, -1, sizeof(hash));    memset(a[0], 0, sizeof(a[0]));//注意:    hash[hashcode(a[0], k)] = 0;  //  下标从1开始,但是下标为0也必须加入散列表中,因为如果                                  //  1,2, 3,4是平衡的了,我们比较的是,a[4]和a[0](而不是a[1])是否对应相等。    for (i = 1; i <= n; i++) //下标从1开始    {        scanf ("%d", &id);        for (j = 0; j < k; j++) {           sum[i][j] = sum[i - 1][j] + (1 & (id >> j));           a[i][j] = sum[i][j] - sum[i][0];        }        int p = hashcode(a[i], k), m = 0;        while (hash[p] != -1)        {            for (r = 1; r < k; r++)                if (a[hash[p]][r] != a[i][r])                    break;            if (r == k) {                if (ans < i - hash[p])                     ans = i - hash[p];                break;  //hash[p]的值是所有映射到p这个地址的a[i]数组中最小的i值,所以一旦找到就可直接跳出循环            }            p += 2 * (++m) - 1; //平方探测法            if (p >= SIZE) p -= SIZE;        }        if (hash[p] == -1) //如果没有搜索到,则将目前的插入到表中            hash[p] = i;    }    printf("%d\n", ans);    return 0;}


原创粉丝点击